You can certainly create and manipulate a PointCloud2:

#include "sensor_msgs/msg/point_cloud2.hpp"

int main(int argc, char * argv[])
{
  sensor_msgs::msg::PointCloud2 point_cloud2_msg;
  point_cloud2_msg.data.reserve(10);
  point_cloud2_msg.fields.reserve(10);
  // ...
}

But I don’t know what you mean by fill. You mean from a PCL type or OpenCV type?