What to do if extern "C" include collides with Qt libraries? - c++

In my case, I'm experimenting with QtMultimedia and libffmpeg as decoder.
Imported ffmpeg as extern "C", but the ffmpeg's AVPixelFormat collides with QVideoFrame's PixelFormat.
Exact error:
'AVPixelFormat' : is not a member of 'QVideoFrame'
Does anyone know a possible solution?
EDIT: Code parts.
Part 1: Qt VideoWidget Sample
Part 2: Usage of libffmpeg, based on dranger tutorial
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}

This is caused by the following line in the FFmpeg's pixfmt.h:
#define PixelFormat AVPixelFormat
You can try the following trick then:
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
#undef PixelFormat
#include <qt headers>

You can't blindly extern "C" the headers if they contain C++ code. Even if you make it past that collision you're going to run into problems at link time when your calls try to link to the "C" symbols but the ffmpeg library exports them with C++ linkage.
If you're trying to export C symbols, my advice would be to create a wrapper function that exports C but makes the C++ calls into the library.

Related

vs2015 cuda9.0 linked SHA1_Init with CUDA implement instead of openssl cpu libs

I am a beginner to cuda, c++ and I am trying to move openssl sha1 cpu code to cuda c,but I ran into a weired problem.
here is the minimum code that can reproduce the problem.
There are three files in this vs2015 cuda9.0 project. They are main.cpp ,sha1.cu and sha1.h
//main.cpp
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "openssl\sha.h"
int main()
{
SHA_CTX ctx;
SHA1_Init(&ctx);
return 0;
}
//sha1.h
#ifndef SHA1_H
#define SHA1_H
#include <stdint.h>
#include <cuda_runtime.h>
namespace cudatest {
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} SHA1_CTX;
#define SHA_CTX SHA1_CTX
#define SHA_DIGEST_LENGTH 20
__device__ void SHA1_Init(SHA1_CTX * context);
#ifdef __cplusplus
}
#endif
}
#endif /* SHA1_H */
//sha1.cu
#include <cuda_runtime.h>
#include "sha1.h"
namespace cudatest {
__device__ void SHA1_Init(SHA1_CTX * context)
{
}
}
The main.cpp uses C/C++ compiler and sha1.cu uses CUDA C/C++
And I add openssl headers into the AdditionalIncludeDirectories,set directory which contains ssleay32.lib and libeay32.lib to library path,set AdditionalDependencies with ssleay32.lib, libeay32.lib .
Then the project built with no error and no warning. But when I run it
or debug it,I found the function SHA1_Init runs into device code and
the program crashed immediately.
why the compiler linked function SHA1_Init with the cuda device
SHA1_Init implement which has a namespace cudatest wrapped instead
of a ssleay32.lib, libeay32.lib CPU implement?
OK,I found the problem.I shouldn't use extern "C" in a c++ namespace.It make the function visiable to the global namespace. if you define another c SHA1_Init function in a .cpp file ,the linker will complain.But if another SHA1_Init is in a openssl lib,the vs C/C++ linker warnned nothing but linked to the cuda implement.

Using ffmpeg library with Qt framework results in error

When I include:
extern "C" {
#include <libavcodec/avcodec.h>
}
I am getting the error:
undefined reference to QVideoSurfaceFormat::QVideoSurfaceFormat(QSize
const&, QVideoFrame::AVPixelFormat, QAbstractVideoBuffer::HandleType)
without the include - build success.
My guess that include brings some defines that breaks QVideoSurfaceFormat defenition.
Have someone faced with the similar issue?
#define __STDC_CONSTANT_MACROS // to fix #include <stdint.h> issue
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
After reading through stdint.h and related topic in the web, found solution, that works for me:
#define __STDC_CONSTANT_MACROS

extern "c" behaviour in linux platform

ScriptInterface.h
extern "C"
{
#include "kel.h"
#include "process.h"
#if defined(SIMULATOR_COMPILE_FROM_SCRIPTINTERFACE) || defined(SIMULATOR_WIN)
#include "sigtypes.h"
#endif
}
In windows platform this is not giving any errors(below code)
xyz.cpp
#include "kel.h"
#include "process.h"
#include "sigtypes.h"
#include "ScriptInterface.h"
Whereas it is giving 'Symbol look up error' in Linux platform. Is there any different behavior of extern 'C' in Linux platform?
_Z16KEL_MEM_AllocateP19KEL_MEM_tPoolHandlej is very much a mangled name and it's almost certainly there because you're including kel.h outside of the extern "C" block.
Get rid of the first three includes in xyz.cpp and just use the ones you include from within ScriptInterface.h (which are marked as non-mangling).

ffmpeg in C++ "av_register_all not declared in this scope"

I'm trying to compile this simple program in C++ (in Code Blocks):
#ifdef __cplusplus
extern "C" {
#endif
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#ifdef __cplusplus
};
#endif
int main(int argc, char *argv[]) {
av_register_all();
return 0;
}
However I keep getting the error message:
|11|error: ‘av_register_all’ was not declared in this scope|
Other people seem to have had this problem and adding the extern "C" section seems to have solved it form them but not me. Does anyone have any suggestions?
Thanks
Did you set up your additional libraries / additional include files?
Here you can find how to do it in MSVC++, I have used CodeBlocks a little & never included an external library to it, however I think you should be able to adopt it to CodeBlocks.

Using .c and .cpp files in Visual Studio at the same time

Trying to figure out how to get an application to compile that uses both C and C++ files. Not the entire code, but enough to get the idea:
main.cpp:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
#include "two.h"
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hInst2, LPSTR lpCmdLine, int nShowCmd) {
FunctionOne();
FunctionTwo();
}
one.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <gdiplus.h>
#include <gdiplusflat.h>
using namespace Gdiplus;
using namespace Gdiplus::DllExports;
int FunctionOne() {
}
two.c
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int FunctionTwo() {
}
The header files contain only definitions for those functions.
Now, if I compile this with a main.cpp, I get an "unresolved external symbol" for FunctionTwo. If I compile this with a main.c, I get the same thing for FunctionOne. Is this even possible, and if so, how would I set up the project to compile properly (Visual Studio 2010)?
It compiles fine if I comment out the alternate function depending on the extension for main.
Thanks!
The problem is two.h, it almost certainly wasn't written to allow a C++ compiler to properly compile the C function prototype. You'll want to take advantage of the predefined __cplusplus macro, like this:
two.h:
#ifdef __cplusplus
extern "C" {
#endif
int FunctionTwo();
// etc...
#ifdef __cplusplus
}
#endif
Lovely macro soup ;) If the header is pre-baked and never saw a C++ compiler before then do this in your .cpp source code file:
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "one.h"
extern "C" {
#include "two.h"
}
Some programmers name their header files .hpp if they contain C++ declarations and .h if they contain C declarations. That's a pretty good practice I personally favor. So does the Boost team. It didn't otherwise set the world on fire.
C++ does name-mangling to support function overloading while C does not. You will have to mark your function as extern "C" to prevent name mangling.
// main.cpp
extern "C" int FunctionTwo();
.. the rest ..
// two.c
extern "C" int FunctionTwo() {
// stuff
}
See http://www.parashift.com/c++-faq/mixing-c-and-cpp.html for more information on mixing C and C++.