C-DLL from C++ source - c++

I have a C-Wrapper for my C++ Framework. Since this should run on mac and windows I am using scons:
env = Environment()
env.Append(CPPPATH = ['./'])
env.Append(LIBS = 'kernel32.lib')
env.Append(LIBPATH = 'C:/Program Files/Microsoft SDKs/Windows/v6.0A/Lib')
env.SharedLibrary(target='warpLib', source='warplib.cpp')
Simple Versions of warplib.cpp and warplib.h look like this:
warplib.cpp
#define DllExport __declspec( dllexport )
#include "warplib.h"
extern "C" {
DllExport int foo(int a) {
return a;
}
}
warplib.h
#define DllExport __declspec( dllexport )
extern "C" {
DllExport int foo(int a);
}
Can anybody tell me what is wrong with that? I tried almost all the combinations possible of 'extern "C"' but it always throws me something like "error C2732: linkage specification contradicts earlier specification for '...'".
If I skip 'extern "C"' it works but I see no .lib file and I am pretty sure I need that to really use the library.

You should only need extern "C" on the declaration. Anyone then including that header will expect to link against it using the C linking standard, rather than the C++ decorated form. The warplib.cpp source file, and subsequent object file will expose the function foo correctly if warplib.h is included.
When using MSVC, there are a plethora of semi-useful scripts, and "build environment" console shortcuts provided, with a lot of dev-related environment variables and paths provided. I recommend locating a suitable script to execute to insert these variables into your environment, or running the dev console.

Related

Using a c++ builder application with an external dll

I'm trying to use an external dll in my c++ builder application. The dll (let.s call it X.dll) was created with Qt Creator (using MingW 32 bit compiler, tried gcc as well )
and consists of a single functon to keep things simple (besides X.dll, an import library X.a is also created).
The dll header (Dll_lib.h) is basically just
__declspec(dllexport) Dll_method(float *p, int n);
If I create a simple Qt application, add the dll header to it and link it to the dll import library X.a, everythink works as expected.
However, when I try to use the dll in my c++ builder application, I get an "unresolved external _Dll_method referenced from ..." error.
The part of my c++ builder app that references the dll looks like
#include "lib\Dll_lib.h"
#pragma comment(lib, "X.lib")
__declspec(dllimport) Dll_method(float *p, int n);
.....
X.lib was created directly from the dll using the implib tool that comes bundled with c++ builder. I also tried to create X.lib from X.a using coff2omf tool but nothing worked and I always get the same error message.
C++ environments have a habit of name mangling to support overloads, different arguments with the same name, like:
int use(int x, char y); // mangles to something like use__Int__Chr.
int use(double x); // mangles to something like use__Dbl.
This allows the correct one to be linked depending on the arguments.
You may need to wrap it inside extern "C" to get it to not mangle the name, something like:
extern "C" {
__declspec(dllimport) Dll_method(float *p, int n);
}
That's assuming you're creating it without name mangling and using it from something that assumes it is mangled. If it's mangled on both sides, you'll probably have to create and use it with extern "C" since there's no guarantee different compilers will mangle with the same rules.
As an aside, you should be able to examine the object files or DLLs created by your toolchain, to ascertain what the function is called where it's defined and also what it's expected to be by the caller. Under Linux, I'd use something like nm, I'm not sure what the equivalent is for Windows.

Windows CE .EXE symbol access from DLL

I have some code which is working on Unix (Linux and Solaris) and Windows (7 to be exact) but doesn't work on Windows CE. This code implements a plug-in framework and requires exporting symbols from the executable into the loaded plug-ins. I am unable to get the loaded plug-ins (DLLs) to resolve symbols from the main executable.
I have reduced the interface to a single function in the main executable which is defined as such:
extern "C" __declspec( dllexport )
const char * translate_name( const char *key ) {
...
}
If I run Dumpbin /EXPORTS on the executable I see this as one of the exported symbols:
81 50 00001474 translate_name = #ILT+1135(_translate_name)
The plug-ins are required to export two functions xxxLoadPlugin and xxxUnloadPlugin which the main executable will call after loading to allow them to interconnect. The xxx is replaced with an agreed upon name prefix (usually the dll or .so name). I have a test project which creates:
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
If I compile and run this module everything will work as expected. I can load the dll, and walk through the functions in my debugger.
If I add code which references translate_name, such as:
extern "C" __declspec( dllimport ) const char * translate_name( const char *key );
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
translate_name("test");
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
the DLL will now fail to load. Checking the created DLL with dumpbin /IMPORTS I see:
50 translate_name
translate_name is the only symbol imported from my main executable. If I try using GetProcAddress instead of relying on the linker, like this:
extern "C" __declspec( dllexport ) int testRegisterLibrary( ) {
HMODULE mainModule = GetModuleHandle(NULL); //handle for main executable
void *ptr = (void *)GetProcAddress(L"translate_name");
return 0;
}
extern "C" __declspec( dllexport ) int testUnregisterLibrary( ) {
return 0;
}
The DLL loads, but the value of 'ptr' is NULL (checked inside a debugger). I've also tried GetProcAddressA("translate_name"), and using "_translate_name" with the same results.
Given this it seems that the symbols that were exported by the executable are not retained after the initial loader pass in windows CE. Again, this works in any normal windows environment. Is there some setting I'm missing for windows CE? Why can GetProcAddress not find a symbol in the executable which dumpbin says is exported? Are the symbols being hidden or dropped by the windows CE loader?
Just to confirm your findings, this doesn't work. It is difficult to find hard evidence in the MSDN docs that this is not supported, other than that GetProcAddress() is adamant that the symbol must be exported by a DLL. You can't get the DLL loaded, it will fail with ERROR_BAD_EXE_FORMAT when it contains the import from the EXE. GetProcAddress() will always fail with ERROR_INVALID_HANDLE, even if you force the module handle to the EXE load address.
There's no strong evidence that the loader intentionally strips the export table of the EXE, it is resident in memory when you look with the debugger. It just categorically refuses to look at it.
You'll need to punt this problem and tackle this a different way. Beyond spinning off the helper functions in a separate DLL, an obvious workaround is that you provide the xxxLoadPlugin() entrypoint with an argument, a pointer to table of function pointers to the helper functions. The common IServiceProvider interface used in COM is a good approach.

Chain of C libraries into C++

I have a very trivial problem including a chain of C libraries into a C++ main project. I've experience with C but it's the first time that I'm programming in C++.
The structure of the project is a single folder with inside:
main.cpp
Mylib_1.c
Mylib_1.h
Mylib_2.c
Mylib_2.h
main calls -> Mylib_1.h that calls -> My_lib2.h
//main.cpp
#include "Mylib_1.h"
//Mylib_1.h
#include "Mylib_2.h"
main contains both Mylib_1 and Mylib_2 functions and typedef structs
Mylib_1 uses typedef structs and functions of Mylib_2
Everything inside each Mylib_x.h is wrapped between extern "C", like this:
#ifndef __MYLIB_X_H
#define __MYLIB_X_H
#ifdef __cplusplus
extern "C" {
#endif
mycode
#ifdef __cplusplus
}
#endif
#endif
But when I try to compile it with eclipse kepler on Ubuntu 12.04 x64, I get:
Mylib_1.h error: Mylib_2_type_t does not name a type
main.cpp error: Mylib_2_function1 was not declared in this scope
...
Only the above sections are marked as error in eclipse, the header looks included fine.
Furthermore according to eclipse, the __cplusplus flag is false into Mylib_2.h but true into Mylib_1.h
Thinking of some eclipse error, I've tried to manually build the project via g++ (v4.6.3) but I got the same exact problem when I've tried to link the libraries .o with the main.cpp
Seems stupid but I can't figure out what could it be. Any suggestion?
Thank you
Have you checked that your lines
#ifndef __MYLIB_X_H
#define __MYLIB_X_H
are really different for the two files,
e.g. _MYLIB1_H and _MYLIB2_H?

c++: definition of dllimport function not allowed, building with visual studio 2010

I'm using visual studio 2010 to build a .dll. I wrote up a trial as:
// trialDLL.h
#ifndef TRIALDLL_H_
#define TRIALDLL_H_
// ... MyMathFuncs class definition omitted
#ifdef __cplusplus
extern "C"{
#endif
#ifdef TRIALDLL_EXPORT
#define TRIALDLL_API __declspec(dllexport)
#else
#define TRIALDLL_API __declspec(dllimport)
#endif
TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset);
TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath);
TRIALDLL_API double __stdcall MyAdd(MyMathFuncs* myMath, double a, double b);
// some other similar stuff
#ifdef __cplusplus
}
#endif
#endif
And the triallDLL.cpp file:
// trialDLL.cpp
#include "trialDLL.h"
TRIALDLL_API MyMathFuncs* __stdcall new_MyMathFuncs(double offset)
{
return new MyMathFuncs(offset);
}
TRIALDLL_API void __stdcall del_MyMathFuncs(MyMathFuncs *myMath)
{
delete myMath;
}
TRIALDLL_API double __stdcall MyAdd(MyMathFuncs *myMath, double a, double b)
{
return myMath->Add(a, b);
}
// ... some other definitions
With these two files in the project, I added a property sheet to the project through visual studio 2010 property manager and added TRIALDLL_EXPORT to user macros. After all these, the nice Intellisense gives me error for each function defined in the .cpp file and complains "error: a function declared 'dllimport' may not be defined". So it appears that Intellisense doesn't find TRIALDLL_EXPORT defined. I thought it might make a difference if I actually build the project, but the result suggests the same error: "error C2491: 'new_MyMathFuncs' : definition of dllimport function not allowed". Then it is clear that the macro TRIALDLL_EXPORT is still not defined in compiling time.
After failing to add macro through visual studio, I also tried putting code line: #define TRIALDLL_EXPORT in trialDLL.cpp but it didn't help either. I wonder what's the proper way to do this? How do I inform the compiler that the micro is defined so that TRIALDLL_API evaluates to dllexport rather than dllimport?
Also, if I can build the .dll successfully, is there any systematic way to test/verify the functionality of the .dll?
Thanks for any help in advance! (Although I know it's an issue here on stackoverflow to put appreciation in the question, I feel myself impolite not to do so. Forgive me for any inefficiency caused by these lines.)
"User macros" in VS property sheets have nothing to do with preprocessor macros. Put TRIALDLL_EXPORT into the property sheet's section C/C++ > Preprocessor > Preprocessor Definitions
"User macros," which can only be defined in property sheets, allow you to create your own "variables" usable in Visual Studio properties, similar to the built-in ones $(TargetName), $(SolutionDir) etc.
As said in this Microsoft article, you cannot apply the __declspec(dllimport) keyword to implement a function. You should use it only in the declaration. For example:
// function declaration
void __declspec(dllimport) funcB();
// function definition
void funcB() {
//funcB code
}
Put
#error Where is my macro?
in the #else block of the header. Then experiment with the project settings or the #define until you get it right. Did you perhaps only add the property sheet to one configuration? Did you put the #define at the very top of the file? Do you have any PCH stuff that causes it to ignore your settings? And so on.
The code looks okay, and must work if TRIALDLL_EXPORT is actually defined. You most probably messed up that somehow (like set it for a different configuration or for just one file) or did not rebuild.
If you're completely lost, ask for the preprocessor output, and look at that. As with define there can not be dllimport around at all, the error is also impossible.
EDIT: I just noticed you wrote _I also tried putting code line: #define TRIALDLL_EXPORT in_ trialDLL.cpp. I thought you put it at top of the header for trial. Try that first just to see that it works fine. Then you can remove it after you found the proper place.

making an VC++ .exe to DLL .is it possible?

I have an VC++ win 32 application which compiles into an EXE. But now I want to convert it into dll so that I can load that in another application.I tried changing in Visual Studio properties from .EXE to .DLL which successfully converted it but whn i use GetProcAddress it always returns NULL . I am not sure what I am doing is right or wrong .
Basically this what I want to achieve :
I want to link project 1 and project2
Project 2 should be able to invoke the functions of project1(which is an exe currenlty)
EDIT
Hi guys thanks for your input .I told what you guys said . even then my GetProcAddress returns zero . Am i am doing anything wrong .Shown my dll loading code below .
HINSTANCE LoadMe = LoadLibrary( _T("D:\\VC++Project\\CVAList\\CVAList\\ExportTest.dll"));
if (LoadMe != 0)
printf("LoadMe library loaded!\n");
else
printf("LoadMe library failed to load!\n");
EntryPointfuncPtr LibMainEntryPoint;
LibMainEntryPoint = (EntryPointfuncPtr)GetProcAddress(LoadMe,"PrintFloatsVal");
LibMainEntryPoint (a1 ,a,b,c,d ); // 4 double
EDIT DLL Export Code
#define DllExport __declspec( dllexport )
DllExport void PrintFloatsVal ( int amount, double &d1 ,double &d2 , double &d3 ,double &d4)
{
....
..
}
You need to export the functions you wish to access using the __declspec dllexport keyword.
So if you add the manifest constant 'BUILDING_MY_DLL' to the project, the header file that declares the functions you care about can be used in both the DLL project and any code that uses the DLL:
#ifdef BUILDING_MY_DLL
#define MY_DLL_EXPORT __declspec dllexport
#else
#define MY_DLL_EXPORT __declspec dllimport
#endif
And decorate the functions you wish to export:
MY_DLL_EXPORT BOOL Func1(int a);
If the function you wish to access is implemented in C++ it will be decorated, for the purposes of function overloading and other purposes, and it best accessed directly like any other function. If you wish to use GetProcAddress() however you are better off giving it C-linkage by surrounding the function with extern "C" { ... }. This will make the exported name the same the name used within the code.
Reference: http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx