extern "c" behaviour in linux platform - c++

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).

Related

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

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

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.

Ffmpeg headers do not compile in windows

I am trying to link to ffmpeg under windows, but have run into difficulties. Inclusion of ffmpeg headers causes hundreds of compilation errors which i can't easily fix.
1) timestamp.h uses snprintf instead of _snprintf. I have tried to add it as a macro, like this:
#ifdef Q_OS_WIN
#define snprintf _snprintf
#endif
#define __STDC_CONSTANT_MACROS
namespace ffmpeg {
extern "C" {
#include <libavutil/imgutils.h>
#include <libavutil/samplefmt.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
} }
but it didn't help. Why would the macro not propagate inside?
2) There again, PRId64 isn't defined. I have defined __STDC_CONSTANT_MACROS before inclusion of timestamp.h, but definition isn't retrieved from inttypes.h
In compiler output, it looks like:
ffmpeg\include\libavutil/timestamp.h(42) : error C3861: 'snprintf': identifier not found
ffmpeg\include\libavutil/timestamp.h(42) : error C2146: syntax error : missing ')' before
identifier 'PRId64'
You did include them into a extern "C" right?
extern "C" {
#include <libavutil/imgutils.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}
Is this a typo? You talk about "snprintf" ("n", not "m").
#define smprintf _snprintf
Even then, timestamp.h probably redifines it or includes something that does.

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++.

C++ lnk2005 error on two files with extern "C", why?

I have a CPP with extern "C" functions. If they are all in a single file, everything works great. I want to split up the functions into different files just for organizational purpose.
So lets say I have these two files:
File_One.cpp
#pragma once
#include "stdafx.h"
#include <windows.h>
#include "Functions.h"
#include "Variables.h"
#include <string>
#include "File_Two.cpp"
extern "C"
{
__declspec(dllexport) void MethodOne()
{
MethodTwo();
}
}
File_Two.cpp
#pragma once
#include "stdafx.h"
#include <windows.h>
#include "Functions.h"
#include "Variables.h"
#include <string>
extern "C"
{
__declspec(dllexport) void MethodTwo()
{
}
}
I have tried rearranging my include headers in different order, and even place no include headers in file_one.cpp other than the include for file_two.cpp but I always get the same errors.
1) error LNK1169: one or more multiply defined symbols found
2) error LNK2005: _MethodTwo already defined in File_One.obj
What exactly am I doing wrong?
What should I do to fix it?
Thank you!
You're probably running into issues because you're including the File_two.cpp file in your File_one.cpp file. What is happening is that File_two.cpp and File_one.cpp are getting compiled and linked. But because File_two.cpp is included in File_one.cpp, the linker is seeing two copies of MethodTwo, and can't decide which to use.
You should move the declarations to a header:
File_two.h:
extern "C"
{
__declspec(dllexport) void MethodOne()
}
And include that instead.
File_one.h:
extern "C"
{
__declspec(dllexport) void MethodOne();
}
Then define the functions with their body in their respective .cpp files. No need for extern "C" in the source files.