I'm trying to write a C++ program, that sends a bunch of images and converts them into a RTSP stream. After some grinding, I've came up with the code for that. VLC seems to connect to the server, but it gets no data, then it quits... Can anyone tell me what I'm doing wrong? Thank you!
VLC just tells me this:
main debug: processing request item: rtsp://192.168.56.1/ScreenShots, node: Playlist, skip: 0
main debug: rebuilding array of current - root Playlist
main debug: rebuild done - 1 items, index 0
main debug: starting playback of new item
main debug: resyncing on rtsp://192.168.56.1/ScreenShots
main debug: rtsp://192.168.56.1/ScreenShots is at 0
main debug: creating new input thread
main debug: Creating an input for 'rtsp://192.168.56.1/ScreenShots'
main debug: requesting art for new input thread
main debug: using timeshift granularity of 50 MiB
main debug: using timeshift path: C:\Users\Benny\AppData\Local\Temp
main debug: looking for meta fetcher module matching "any": 1 candidates
main debug: `rtsp://192.168.56.1/ScreenShots' gives access `rtsp' demux `any' path `192.168.56.1/ScreenShots'
main debug: creating demux: access='rtsp' demux='any' location='192.168.56.1/ScreenShots' file='\\192.168.56.1\ScreenShots'
main debug: looking for access_demux module matching "rtsp": 15 candidates
lua debug: Trying Lua scripts in C:\Users\Benny\AppData\Roaming\vlc\lua\meta\fetcher
lua debug: Trying Lua scripts in C:\Program Files\VideoLAN\VLC\lua\meta\fetcher
main debug: no meta fetcher modules matched
main debug: looking for art finder module matching "any": 2 candidates
live555 debug: version 2016.11.28
lua debug: Trying Lua scripts in C:\Users\Benny\AppData\Roaming\vlc\lua\meta\art
lua debug: Trying Lua scripts in C:\Program Files\VideoLAN\VLC\lua\meta\art
lua debug: Trying Lua playlist script C:\Program Files\VideoLAN\VLC\lua\meta\art\00_musicbrainz.luac
lua debug: skipping script (unmatched scope) C:\Program Files\VideoLAN\VLC\lua\meta\art\00_musicbrainz.luac
lua debug: Trying Lua playlist script C:\Program Files\VideoLAN\VLC\lua\meta\art\01_googleimage.luac
lua debug: skipping script (unmatched scope) C:\Program Files\VideoLAN\VLC\lua\meta\art\01_googleimage.luac
lua debug: Trying Lua playlist script C:\Program Files\VideoLAN\VLC\lua\meta\art\02_frenchtv.luac
lua debug: skipping script (unmatched scope) C:\Program Files\VideoLAN\VLC\lua\meta\art\02_frenchtv.luac
lua debug: Trying Lua playlist script C:\Program Files\VideoLAN\VLC\lua\meta\art\03_lastfm.luac
lua debug: skipping script (unmatched scope) C:\Program Files\VideoLAN\VLC\lua\meta\art\03_lastfm.luac
main debug: no art finder modules matched
live555 debug: RTP subsession 'video/H264'
qt debug: IM: Setting an input
main debug: selecting program id=0
live555 debug: setup start: 0.000000 stop:0.000000
live555 debug: We have a timeout of 65 seconds
live555 debug: play start: 0.000000 stop:0.000000
main debug: using access_demux module "live555"
main debug: looking for packetizer module matching "any": 25 candidates
h264 debug: found NAL_SPS (sps_id=7)
h264 debug: found NAL_PPS (pps_id=7 sps_id=7)
main debug: using packetizer module "h264"
main debug: looking for video decoder module matching "any": 19 candidates
avcodec debug: using ffmpeg Lavc58.6.103
avcodec debug: CPU flags: 0x000fd3db
avcodec debug: allowing 6 thread(s) for decoding
avcodec debug: codec (h264) started
avcodec debug: using frame thread mode with 6 threads
main debug: using video decoder module "avcodec"
main debug: looking for meta reader module matching "any": 2 candidates
lua debug: Trying Lua scripts in C:\Users\Benny\AppData\Roaming\vlc\lua\meta\reader
lua debug: Trying Lua scripts in C:\Program Files\VideoLAN\VLC\lua\meta\reader
lua debug: Trying Lua playlist script C:\Program Files\VideoLAN\VLC\lua\meta\reader\filename.luac
main debug: no meta reader modules matched
main debug: `rtsp://192.168.56.1/ScreenShots' successfully opened
live555 error: no data received in 10s, aborting
main debug: EOF reached
main debug: killing decoder fourcc `h264'
main debug: removing module "avcodec"
main debug: removing module "h264"
main debug: removing module "live555"
main debug: Program doesn't contain anymore ES
main debug: dead input
main debug: changing item without a request (current 0/1)
main debug: nothing to play
qt debug: IM: Deleting the input
Here is how I do this in code:
Starting the server:
void startServer(void * aArg) {
rtspServer = new OTPRTSPServer(554);
if (!rtspServer->init(DEFAULT_MONITOR.maxResolution.width, DEFAULT_MONITOR.maxResolution.height, 20)) {
cerr << "Could not start the RTSP Server" << endl;
exit(1);
}
rtspServer->addSession("ScreenShots");
rtspServer->play();
readyToSetFrame = true;
rtspServer->doEvent();
}
Here are the RTSPServer functions that I've wrote:
bool init(int srcWidth, int srcHeight, int fps) {
m_srcWidth = srcWidth;
m_srcHeight = srcHeight;
m_fps = fps;
OutPacketBuffer::maxSize = 100000;
int cNameLen = 100;
m_cName.resize(cNameLen + 1, 0);
gethostname((char*)&(m_cName[0]), cNameLen);
m_rtspServer = RTSPServer::createNew(*m_env, m_rtspPort, nullptr);
if (m_rtspServer == nullptr) {
std::cerr << "Failed to create RTSP server: " << m_env->getResultMsg() << std::endl;
return false;
}
m_screenSource = ScreenSource::createNew(*m_env, m_srcWidth * m_srcHeight, 10);
if (!m_screenSource->openEncoder(m_srcWidth, m_srcHeight, m_fps)) {
std::cerr << "Failed to open X264 encoder: " << std::endl;
return false;
}
return true;
}
void addSession(const std::string& streamName) {
sockaddr_storage destinationAddress;
((struct sockaddr_in&)destinationAddress).sin_addr.s_addr = chooseRandomIPv4SSMAddress(*m_env);
const Port rtpPort(m_rtpPortNum);
const Port rtcpPort(m_rtcpPortNum);
auto rtpGroupSock = new Groupsock(*m_env, destinationAddress, rtpPort, m_ttl);
m_rtpGroupSock->multicastSendOnly();
auto rtcpGroupSock = new Groupsock(*m_env, destinationAddress, rtcpPort, m_ttl);
m_rtcpGroupSock->multicastSendOnly();
m_videoSink = H264VideoRTPSink::createNew(*m_env, rtpGroupSock, m_rtpPayloadFormat);
m_rtcp = RTCPInstance::createNew(*m_env, rtcpGroupSock, m_estimatedSessionBandwidth, &(m_cName[0]), m_videoSink, nullptr, True);
auto sms = ServerMediaSession::createNew(*m_env, streamName.c_str(), "Screen image", "Image from the screen", True);
sms->addSubsession(PassiveServerMediaSubsession::createNew(*m_videoSink, m_rtcp));
m_rtspServer->addServerMediaSession(sms);
std::cout << "Play this stream using the Local URL: " << m_rtspServer->rtspURL(sms) << std::endl;
}
inline void play() {
m_videoES = m_screenSource;
m_videoSource = H264VideoStreamFramer::createNew(*m_env, m_videoES);
m_videoSink->startPlaying(*m_videoSource, nullptr, nullptr);
}
inline void doEvent() {
std::cout << "Doing event loop..." << std::endl;
m_env->taskScheduler().doEventLoop();
std::cout << "Done doing event loop" << std::endl;
}
inline void streamImage(const uint8_t* src, const int index) {
m_screenSource->encode(src);
}
Related
I am trying to make a connection between an EC2 instance (running Amazon Linux 2) and AWS IoT Core using the AWS SDK For C++. Here is the code responsible for making the connection:
#include <aws/crt/Api.h>
#include <aws/iot/MqttClient.h>
#include <iostream>
using namespace Aws::Crt;
/************************ Setup the Lib ****************************/
/*
* Do the global initialization for the API.
* Set the configuration
*/
const String endpoint = "a19cezbd6aruk0-ats.iot.eu-west-1.amazonaws.com";
const String certificatePath = "../SSL/5588197ef3-certificate.pem.crt";
const String keyPath = "../SSL/5588197ef3-private.pem.key";
const String sendTopic = "send";
const String receiveTopic = "get";
const String clientId = "turnstile";
const String caFile = "../SSL/AmazonRootCA1.pem";
ApiHandle apiHandle;
/********************** Now Setup an Mqtt Client ******************/
/*
* You need an event loop group to process IO events.
* If you only have a few connections, 1 thread is ideal
*/
auto makeConnection ( ) {
Io::EventLoopGroup eventLoopGroup(1);
if (!eventLoopGroup) {
fprintf(
stderr, "Event Loop Group Creation failed with error %s\n", ErrorDebugString(eventLoopGroup.LastError()));
exit(-1);
}
Aws::Crt::Io::DefaultHostResolver defaultHostResolver(eventLoopGroup, 1, 5);
Io::ClientBootstrap bootstrap(eventLoopGroup, defaultHostResolver);
if (!bootstrap) {
fprintf(stderr, "ClientBootstrap failed with error %s\n", ErrorDebugString(bootstrap.LastError()));
exit(-1);
}
Aws::Iot::MqttClientConnectionConfigBuilder builder;
builder = Aws::Iot::MqttClientConnectionConfigBuilder(certificatePath.c_str(), keyPath.c_str());
builder.WithCertificateAuthority(caFile.c_str());
builder.WithEndpoint(endpoint);
auto clientConfig = builder.Build();
if (!clientConfig) {
fprintf(
stderr,
"Client Configuration initialization failed with error %s\n",
ErrorDebugString(clientConfig.LastError()));
exit(-1);
}
Aws::Iot::MqttClient mqttClient(bootstrap);
/*
* Since no exceptions are used, always check the bool operator
* when an error could have occurred.
*/
if (!mqttClient) {
fprintf(stderr, "MQTT Client Creation failed with error %s\n", ErrorDebugString(mqttClient.LastError()));
exit(-1);
}
/*
* Now create a connection object. Note: This type is move only
* and its underlying memory is managed by the client.
*/
auto connection = mqttClient.NewConnection(clientConfig);
if (!connection) {
fprintf(stderr, "MQTT Connection Creation failed with error %s\n", ErrorDebugString(mqttClient.LastError()));
exit(-1);
}
return connection;
}
However, it returns the following error when attempting to run, not compile (which it does quite smoothly)
[ec2-user#ip-172-31-23-254 build]$ cmake3 -DCMAKE_INSTALL_PREFIX="/home/ec2-user/MakerSpaceTurnstile" -DCMAKE_BUILD_TYPE="Release" ..
-- LibCrypto Include Dir: /home/ec2-user/MakerSpaceTurnstile/include
-- LibCrypto Shared Lib: /lib64/libcrypto.so
-- LibCrypto Static Lib: /home/ec2-user/MakerSpaceTurnstile/lib64/libcrypto.a
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ec2-user/MakerSpaceTurnstile/src/build
[ec2-user#ip-172-31-23-254 build]$ sudo cmake3 --build .Scanning dependencies of target MakerSpaceIoT
[ 50%] Building CXX object CMakeFiles/MakerSpaceIoT.dir/main.cpp.o
[100%] Linking CXX executable MakerSpaceIoT
[100%] Built target MakerSpaceIoT
[ec2-user#ip-172-31-23-254 build]$ ./MakerSpaceIoT
Fatal error condition occurred in /home/ec2-user/MakerSpaceIoT/Code/awssdk/aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-c-common/source/allocator.c:115: allocator != ((void *)0)
Exiting Application
################################################################################
Stack trace:
################################################################################
./MakerSpaceIoT(aws_backtrace_print+0x50) [0x5c27f4]
./MakerSpaceIoT(aws_fatal_assert+0x50) [0x5ba010]
./MakerSpaceIoT(aws_mem_acquire+0x68) [0x5b9574]
./MakerSpaceIoT(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcEN3Aws3Crt12StlAllocatorIcEEEC2EPKcRKS6_+0xb8) [0x438818]
./MakerSpaceIoT() [0x432420]
./MakerSpaceIoT(__libc_csu_init+0x60) [0x5c75c0]
/lib64/libc.so.6(__libc_start_main+0x8c) [0xffff92728c8c]
./MakerSpaceIoT() [0x432a30]
Aborted
What could be going wrong here? The policy on IoT Core seems to allow the topics as well as the client ID.
So turns out it is because the handler is out of the scope of the function.
OS : win10 64 bits
compiler : vc2017 64bits
vlc version : 3.0.9.2 from here
Source codes
#include <vlc/vlc.h>
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <vector>
void libvlc_callback(libvlc_event_t const *event, void*)
{
switch (event->type) {
case libvlc_MediaMetaChanged:
std::cout<<__func__<<": libvlc_MediaMetaChanged = "<<event->u.media_meta_changed.meta_type<<std::endl;
break;
case libvlc_MediaSubItemAdded:
std::cout<<__func__<<": libvlc_MediaSubItemAdded = "<<event->u.media_subitem_added.new_child<<std::endl;
break;
case libvlc_MediaDurationChanged:
std::cout<<__func__<<": libvlc_MediaDurationChanged = "
<<event->u.media_duration_changed.new_duration<<std::endl;
break;
case libvlc_MediaParsedChanged:
std::cout<<__func__<<": libvlc_MediaParsedChanged = "<<event->u.media_parsed_changed.new_status<<std::endl;
break;
case libvlc_MediaFreed:
std::cout<<__func__<<": libvlc_MediaFreed = "<<event->u.media_freed.md<<std::endl;
break;
case libvlc_MediaStateChanged:
std::cout<<__func__<<":libvlc_MediaStateChanged = "<<event->u.media_state_changed.new_state<<std::endl;
break;
default:
break;
}
}
std::vector<libvlc_event_e> create_events()
{
return {libvlc_MediaMetaChanged,
libvlc_MediaSubItemAdded,
libvlc_MediaDurationChanged,
libvlc_MediaParsedChanged,
libvlc_MediaFreed,
libvlc_MediaStateChanged};
}
int main()
{
libvlc_instance_t *inst = libvlc_new(0, nullptr);
char const *location = "C:/Users/ssss/audio/audio.mp3";
libvlc_media_t *vlc_media = libvlc_media_new_location(inst, location);
libvlc_event_manager_t *vlc_events = libvlc_media_event_manager(vlc_media);
for(libvlc_event_e const &event : create_events()){
libvlc_event_attach(vlc_events, event, libvlc_callback, nullptr);
}
libvlc_media_add_option(vlc_media, "--sout='#transcode{acodec=s16l, ab=16, channels=1, samplerate=16000}:"
"std{access=file, mux=wav, "
"dst=\"audio.wav\"}'");
std::this_thread::sleep_for(std::chrono::seconds(10));
libvlc_media_release(vlc_media);
libvlc_release(inst);
}
The output I got are
main libvlc debug: VLC media player - 3.0.9.2 Vetinari
main libvlc debug: Copyright © 1996-2020 the VideoLAN team
main libvlc debug: revision 3.0.9.2-0-gd4c1aefe4d
main libvlc debug: configured with ../extras/package/win32/../../../configure '--enable-update-check' '--enable-lua' '--enable-faad' '--enable-flac' '--enable-theora' '--enable-avcodec' '--enable-merge-ffmpeg' '--enable-dca' '--enable-mpc' '--enable-libass' '--enable-schroedinger' '--enable-realrtsp' '--enable-live555' '--enable-dvdread' '--enable-shout' '--enable-goom' '--enable-caca' '--enable-qt' '--enable-skins2' '--enable-sse' '--enable-mmx' '--enable-libcddb' '--enable-zvbi' '--disable-telx' '--enable-nls' '--host=x86_64-w64-mingw32' '--with-breakpad=https://win.crashes.videolan.org' 'host_alias=x86_64-w64-mingw32' 'PKG_CONFIG_LIBDIR=/home/jenkins/workspace/vlc-release/windows/vlc-release-win32-x64/contrib/x86_64-w64-mingw32/lib/pkgconfig'
main libvlc debug: using multimedia timers as clock source
main libvlc debug: min period: 1 ms, max period: 1000000 ms
main libvlc debug: searching plug-in modules
main libvlc debug: loading plugins cache file C:\vlc-3.0.9.2-win64\plugins\plugins.dat
main libvlc warning: cannot read C:\vlc\vlc-3.0.9.2-win64\plugins\plugins.dat: No such file or directory
main libvlc debug: recursively browsing `C:\vlc\vlc-3.0.9.2-win64\plugins'
main libvlc debug: plug-ins loaded: 494 modules
main logger debug: looking for logger module matching "any": 2 candidates
main logger debug: using logger module "console"
main libvlc debug: translation test: code is "C"
main keystore debug: looking for keystore module matching "memory": 3 candidates
main keystore debug: using keystore module "memory"
main libvlc debug: CPU has capabilities MMX MMXEXT SSE SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 FPU
libvlc_callback: libvlc_MediaFreed = 000001DBD602CC50
main libvlc debug: exiting
main libvlc debug: no exit handler
main libvlc debug: removing all interfaces
main keystore debug: removing module "memory"
I cannot see any audio.wav generated in the folder, which step I missed or done it wrong? Thanks
Edit: pass parameters into libvlc_new
const char * const vlc_args[] = {
"--sout",
"#transcode{acodec=s16l,channels=2,samplerate=44100}:std{access=file,mux=wav,dst=\"C:/my_path/clip_0002.wav\"}",
"C:/my_path/audio.wav"};
libvlc_instance_t *inst = libvlc_new(3, vlc_args);
std::this_thread::sleep_for(std::chrono::seconds(60));
libvlc_release(inst);
It give me output message
main libvlc debug: exiting
main libvlc debug: no exit handler
main libvlc debug: removing all interfaces
main keystore debug: removing module "memory"
Don't know why the output file 'audio.wav' never generated in the folder
Found a solution, you need to play the media and open the file correctly, for simplicity I use "libvlc_media_new_path" in this example, if you are using "libvlc_media_new_location", remember to append "file:///" before the location and change to native separator.
#include "core/vlc_error.hpp"
#include <vlc/vlc.h>
#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <QString>
void libvlc_callback(libvlc_event_t const *event, void*)
{
switch (event->type) {
case libvlc_MediaMetaChanged:
std::cout<<__func__<<": libvlc_MediaMetaChanged = "<<event->u.media_meta_changed.meta_type<<std::endl;
break;
case libvlc_MediaSubItemAdded:
std::cout<<__func__<<": libvlc_MediaSubItemAdded = "<<event->u.media_subitem_added.new_child<<std::endl;
break;
case libvlc_MediaDurationChanged:
std::cout<<__func__<<": libvlc_MediaDurationChanged = "
<<event->u.media_duration_changed.new_duration<<std::endl;
break;
case libvlc_MediaParsedChanged:
std::cout<<__func__<<": libvlc_MediaParsedChanged = "<<event->u.media_parsed_changed.new_status<<std::endl;
break;
case libvlc_MediaFreed:
std::cout<<__func__<<": libvlc_MediaFreed = "<<event->u.media_freed.md<<std::endl;
break;
case libvlc_MediaStateChanged:
std::cout<<__func__<<":libvlc_MediaStateChanged = "<<event->u.media_state_changed.new_state<<std::endl;
break;
default:
break;
}
}
std::vector<libvlc_event_e> create_events()
{
return {libvlc_MediaMetaChanged,
libvlc_MediaSubItemAdded,
libvlc_MediaDurationChanged,
libvlc_MediaParsedChanged,
libvlc_MediaListEndReached,
libvlc_MediaFreed,
libvlc_MediaStateChanged};
}
int main()
{
libvlc_instance_t *inst = libvlc_new(0, nullptr);
char const *location = "clip_0002.wav";
libvlc_media_t *vlc_media = libvlc_media_new_path(inst, location);
libvlc_event_manager_t *vlc_events = libvlc_media_event_manager(vlc_media);
for(libvlc_event_e const &event : create_events()){
libvlc_event_attach(vlc_events, event, libvlc_callback, nullptr);
}
QString const cmd("transcode{acodec=s16l, ab=16, channels=1, samplerate=16000}:"
"std{access=file, mux=wav, "
"dst='audio.wav'}");
QString config = ":sout=#duplicate{dst=display,dst=\"%1\"}";
config = config.arg(cmd);
std::cout<<"-------------------------"<<std::endl;
std::cout<<config.toStdString()<<std::endl;
libvlc_media_add_option(vlc_media, ":sout-all");
qt_vlc::vlc_error::show_err_msg();
libvlc_media_add_option(vlc_media, config.toUtf8().data());
qt_vlc::vlc_error::show_err_msg();
libvlc_media_player_t *vlc_player = libvlc_media_player_new_from_media(vlc_media);
libvlc_audio_set_mute(vlc_player, true);
libvlc_media_player_play(vlc_player);
while(1){
qt_vlc::vlc_error::show_err_msg();
if(libvlc_media_get_state(vlc_media) == libvlc_Ended){
break;
}
std::cout<<"media state = "<<libvlc_media_get_state(vlc_media)<<std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
libvlc_media_player_release(vlc_player);
libvlc_media_release(vlc_media);
libvlc_release(inst);
}
You can convert video to audio by this solution too, problem is it will show the video when converting, finding a way to hide the video.
I am using Xcode 11.4 on MacOS Catalina 10.15.3
I use HomeBrew to install SDL2 by Terminal:
brew install sdl2
and then, I open Xcode, create new project named SDL2Tutorial to test the library.
I changed the header search path to
/usr/local/include
and added /usr/local/cellar/sdl2/2.0.12_1/lib/libSDL2-2.0.0.dylib to Link Binary With Library
In main.cpp I wrote code like this
#include <iostream>
#include <SDL2/SDL.h>
int main(int argc, char * argv[]) {
// insert code here...
if (SDL_Init( SDL_INIT_EVERYTHING ) < 0)
{
std::cout << "Error: " << SDL_GetError() << std::endl;
}
return EXIT_SUCCESS;
}
and there are a lot of errors appeared including:
2020-04-02 17:03:41.767966+0700 SDL2Tutorial[829:23149] Metal API Validation Enable
2020-04-02 17:03:41.799979+0700 SDL2Tutorial[829:23443] flock failed to lock maps file: errno = 35
2020-04-02 17:03:41.800445+0700 SDL2Tutorial[829:23443] flock failed to lock maps file: errno = 35
2020-04-02 17:03:41.848181+0700 SDL2Tutorial[829:23149] [plugin] AddInstanceForFactory: No factory registered for id F8BB1C28-BAE8-11D6-9C31-00039315CD46
2020-04-02 17:03:41.875838+0700 SDL2Tutorial[829:23149] HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
2020-04-02 17:03:41.876282+0700 SDL2Tutorial[829:23149] HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine
Did I miss any step of setting up the library and how can I solve all of the errors?
Situation:
I'm attempting to get coverage reports on all python code in my current project. I've utilized Coverage.py with great success for the most part. Currently I'm using it like this taking advantage of the sitecustomize.py process. For everything that's being started from the command line, and it works amazing.
Issue:
I can't get python modules run from C++ via PyImport_Import() type statements to actually trace and output coverage data.
Example:
[test.cpp]
#include <stdio.h>
#include <iostream>
#include <Python.h>
int main()
{
Py_Initialize();
PyObject* sysPath = PySys_GetObject("path");
PyList_Append(sysPath, PyString_FromString("."));
// Load the module
PyObject *pName = PyString_FromString("test_mod");
PyObject *pModule = PyImport_Import(pName);
if (pModule != NULL) {
std::cout << "Python module found\n";
// Load all module level attributes as a dictionary
PyObject *pDict = PyModule_GetDict(pModule);
PyObject *pFunc = PyObject_GetAttrString(pModule, "getInteger");
if(pFunc)
{
if(PyCallable_Check(pFunc))
{
PyObject *pValue = PyObject_CallObject(pFunc, NULL);
std::cout << PyLong_AsLong(pValue) << std::endl;
}
else
{
printf("ERROR: function getInteger()\n");
}
}
else
{
printf("ERROR: pFunc is NULL\n");
}
}
else
std::cout << "Python Module not found\n";
return 0;
}
[test_mod.py]
#!/bin/python
def getInteger():
print('Python function getInteger() called')
c = 100*50/30
return c
print('Randomness')
Output:
If I manually run test_mod.py it outputs as expected. However, if I run the compiled test.cpp binary, it doesn't output anything for coverage data. I know sitecustomize.py is still being hit, as I added some debugging to ensure I wasn't going insane. I can also see in the coverage debug log that it does indeed want to trace the module..
[cov.log]
New process: executable: /usr/bin/python
New process: cmd: ???
New process: parent pid: 69073
-- config ----------------------------------------------------
_include: None
_omit: None
attempted_config_files: /tmp/.coveragerc
branch: True
concurrency: thread
multiprocessing
config_files: /tmp/.coveragerc
cover_pylib: False
data_file: /tmp/python_data/.coverage
debug: process
trace
sys
config
callers
dataop
dataio
disable_warnings: -none-
exclude_list: #\s*(pragma|PRAGMA)[:\s]?\s*(no|NO)\s*(cover|COVER)
extra_css: None
fail_under: 0.0
html_dir: htmlcov
html_title: Coverage report
ignore_errors: False
note: None
New Section 1 Page 2note: None
parallel: True
partial_always_list: while (True|1|False|0):
if (True|1|False|0):
partial_list: #\s*(pragma|PRAGMA)[:\s]?\s*(no|NO)\s*(branch|BRANCH)
paths: {'source': ['/tmp/python_source', '/opt/test']}
plugin_options: {}
plugins: -none-
precision: 0
report_include: None
report_omit: None
run_include: None
run_omit: None
show_missing: False
skip_covered: False
source: /opt/test/
timid: False
xml_output: coverage.xml
xml_package_depth: 99
-- sys -------------------------------------------------------
version: 4.5.4
coverage: /usr/lib64/python2.7/site-packages/coverage/__init__.pyc
cover_paths: /usr/lib64/python2.7/site-packages/coverage
pylib_paths: /usr/lib64/python2.7
tracer: PyTracer
plugins.file_tracers: -none-
plugins.configurers: -none-
config_files: /tmp/.coveragerc
configs_read: /tmp/.coveragerc
data_path: /tmp/python_data/.coverage
python: 2.7.5 (default, Jun 11 2019, 14:33:56) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
platform: Linux-3.10.0-1062.el7.x86_64-x86_64-with-redhat-7.7-Maipo
implementation: CPython
executable: /usr/bin/python
cwd: /opt/test
path: /usr/lib64/python27.zip
/usr/lib64/python2.7
/usr/lib64/python2.7/plat-linux2
/usr/lib64/python2.7/lib-tk
/usr/lib64/python2.7/lib-old
/usr/lib64/python2.7/lib-dynload
/usr/lib64/python2.7/site-packages
environment: COVERAGE_DEBUG = process,trace,sys,config,callers,dataop,dataio
COVERAGE_DEBUG_FILE = /tmp/cov.log
COVERAGE_PROCESS_START = /tmp/.coveragerc
command_line: ???
source_match: /opt/test
source_pkgs_match: -none-
include_match: -none-
omit_match: -none-
cover_match: -none-
pylib_match: -none-
-- end -------------------------------------------------------
<module> : /usr/lib64/python2.7/site.py #556
New Section 1 Page 3<module> : /usr/lib64/python2.7/site.py #556
main : /usr/lib64/python2.7/site.py #539
addsitepackages : /usr/lib64/python2.7/site.py #317
addsitedir : /usr/lib64/python2.7/site.py #190
addpackage : /usr/lib64/python2.7/site.py #152
<module> : <string> #1
process_startup : /usr/lib64/python2.7/site-packages/coverage/control.py #1289
start : /usr/lib64/python2.7/site-packages/coverage/control.py #690
_init : /usr/lib64/python2.7/site-packages/coverage/control.py #362
_write_startup_debug : /usr/lib64/python2.7/site-packages/coverage/control.py #382
write_formatted_info : /usr/lib64/python2.7/site-packages/coverage/debug.py #120
Not tracing '/usr/lib64/python2.7/threading.py': falls outside the --source trees
<module> : /usr/lib64/python2.7/site.py #556
main : /usr/lib64/python2.7/site.py #539
addsitepackages : /usr/lib64/python2.7/site.py #317
addsitedir : /usr/lib64/python2.7/site.py #190
addpackage : /usr/lib64/python2.7/site.py #152
<module> : <string> #1
process_startup : /usr/lib64/python2.7/site-packages/coverage/control.py #1289
start : /usr/lib64/python2.7/site-packages/coverage/control.py #701
start : /usr/lib64/python2.7/site-packages/coverage/collector.py #318
settrace : /usr/lib64/python2.7/threading.py #99
_trace : /usr/lib64/python2.7/site-packages/coverage/pytracer.py #111
_should_trace : /usr/lib64/python2.7/site-packages/coverage/control.py #593
[... Not tracing a bunch of common python code ...]
Tracing './test_mod.py'
<module> : ./test_mod.py #3
_trace : /usr/lib64/python2.7/site-packages/coverage/pytracer.py #111
_should_trace : /usr/lib64/python2.7/site-packages/coverage/control.py #593
I reproduced the issue using your code and you only forgot to call Py_Finalize(). As a result, the report is never generated whereas the data were collected.
It works with the following piece of code:
#include <stdio.h>
#include <iostream>
#include <Python.h>
int main()
{
Py_Initialize();
PyEval_InitThreads();
PyObject* sysPath = PySys_GetObject("path");
PyList_Append(sysPath, PyString_FromString("."));
// Load the module
PyObject *pName = PyString_FromString("test_mod");
PyObject *pModule = PyImport_Import(pName);
if (pModule != NULL) {
std::cout << "Python module found\n";
// Load all module level attributes as a dictionary
PyObject *pDict = PyModule_GetDict(pModule);
PyObject *pFunc = PyObject_GetAttrString(pModule, "getInteger");
if(pFunc)
{
if(PyCallable_Check(pFunc))
{
PyObject *pValue = PyObject_CallObject(pFunc, NULL);
std::cout << PyLong_AsLong(pValue) << std::endl;
}
else
{
printf("ERROR: function getInteger()\n");
}
}
else
{
printf("ERROR: pFunc is NULL\n");
}
}
else
std::cout << "Python Module not found\n";
Py_Finalize();
return 0;
PyObject *PySys_GetObject(char *name) returns a borrowed reference. Is not it the case that the reference count should be incremented? What about:
// ...
PyObject* sysPath = PySys_GetObject("path");
Py_INCREF(sysPath);
PyList_Append(sysPath, PyString_FromString("."));
Py_DECREF(sysPath);
// sysPath = NULL;
// ...
I'm only just starting with the Python-C API myself, but my understanding is that importing modules doesn't actually add them to your main module. You need to do that separately. I'm not sure if this will help with your issue, but my approach that's worked (minus the error checking) has been as follows:
// Initialize main module
PyObject* mainModule = PyImport_AddModule("__main__");;
// Initialize module to be added
PyObject* moduleNamePyObject= PyUnicode_DecodeFSDefault("moduleName");
PyImport_Import(moduleNamePyObject);
// Add module to main module
PyObject_SetAttrString(mainModulePtr, "moduleName", modulePyObject);
Normally, when importing a module, Python tries to find the module file next to the importing module (the module that contains the import statement). Python then tries the directories in “sys.path”. The current working directory is usually not considered. In our case, the import is performed via the API, so there is no importing module in whose directory Python could search for “test_mod.py”. The plug-in is also not on “sys.path”. One way of enabling Python to find the plug-in is to add the current working directory to the module search path by doing the equivalent of “sys.path.append(‘.’)” via the API.
Py_Initialize();
PyObject* sysPath = PySys_GetObject((char*)"path");
PyObject* programName = PyString_FromString(<DIRECTORY>.c_str());
PyList_Append(sysPath, programName);
Py_DECREF(programName);
If you are using python3 ,
Change PyString_FromString to PyUnicode_FromString.
Sources :
https://realmike.org/blog/2012/07/08/embedding-python-tutorial-part-1/
Python Embedding: PyImport_Import not from the current directory
I am confronted to a very weird problem.
When running my very simple one file program via NetBeans, I have the following error:
RUN FINISHED; Segmentation fault; core dumped; real time: 150ms; user: 0ms; system: 0ms
My run command is simple ./Name-Of-The-File.
When I use a terminal and cd to the folder containing the program and run the same command, I get the following output:
Hullo
PLatform Number is : 1
Hullo
(Note that the Hullos were added to pinpoint where the segfault happened, as my very first line in main() prints Hullo.)
Here is the code of the program:
/*
* File: main.cpp
* Author: sysgen
*
* Created on June 4, 2015, 7:08 PM
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <utility>
#include <CL/cl.hpp>
const std::string hw("Hello World \n");
/*
*
*/
//OpenCL Error checking function
inline void checkErr(cl_int err, const char *name){
if (err != CL_SUCCESS){
std::cerr << "FATAL OPENCL ERROR: " << name << "( " << err << ") " << std::endl;
exit(EXIT_FAILURE);
}
}
int main(void) {
//Creating an OpenCL context
std::cout << "Hullo" << std::endl;
cl_int err;
std::vector< cl::Platform > platformList; //We make a vector which will contain the platforms
cl::Platform::get(&platformList);
checkErr(platformList.size() !=0 ? CL_SUCCESS : -1, "cl::Platform::get");
std::cerr << "PLatform Number is : " << platformList.size() << std::endl;
std::string platformVendor;
platformList[0].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor);
std::cout << "Hullo" << std::endl;
return 0;
}
This error also manifests in codeblocks. There is more details produced by gdb:
Building to ensure sources are up-to-date
Selecting target:
Debug
Adding source dir: /home/sysgen/NetBeansProjects/OpenCL SVOGL/
Adding source dir: /home/sysgen/NetBeansProjects/OpenCL SVOGL/
Adding file: /home/sysgen/NetBeansProjects/OpenCL SVOGL/bin/Debug/OpenCL SVOGL
Changing directory to: "/home/sysgen/NetBeansProjects/OpenCL SVOGL/."
Set variable: LD_LIBRARY_PATH=.:/opt/AMDAPPSDK-3.0-0-Beta/lib/x86_64/:/usr/lib32
Starting debugger: /usr/bin/gdb -nx -fullname -quiet -args "/home/sysgen/NetBeansProjects/OpenCL SVOGL/bin/Debug/OpenCL SVOGL"
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Reading symbols from /home/sysgen/NetBeansProjects/OpenCL SVOGL/bin/Debug/OpenCL SVOGL...(no debugging symbols found)...done.
Debugger name and version: GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9
Program received signal SIGSEGV, Segmentation fault.
In ?? () ()
177 dlerror.c: No such file or directory.
#1 0x00007ffff70dd6fd in init () at dlerror.c:177