Reputation: 1247
I am using QT and it's QLibrary to use a DLL. But I can't seem to load the function inside it and use it in my project.
void Compose3wnThread::GenPrinterFile()
{
lib_3wn = new QLibrary;
lib_3wn->setFileName(qApp->applicationDirPath() + "/" + MyDLL);
lib_3wn->load();
if (lib->isLoaded())
{
typedef int (*initial)(char*, int, char*);
initial function = (initial)lib_3wn->resolve("API_Initial");
int result;
result = 0;
//result = (int)function("Nobel Superfine", 12, "D:\\final.3wn");
}
}
lib_3wn is the QLibrary object that holds my DLL. And after runnning the code above, the function remains 0x0 or does not have any value. This is the function I need to load from the DLL.
int API_Initial(char *machineType, int totalLayers, char *fileName)
This function is from a document that defines the functions inside the DLL I'm using. I did not create the DLL myself.
How do I fix this?
Upvotes: 0
Views: 191
Reputation: 1247
Thank you for all the answers. I kinda fixed it using the comment of @Antonio Dias. I used Dependency Walker and then I saw that the DLL I mentioned is dependent(punt not intended) on two[2] other DLL files.
The prior code is already correct.
Upvotes: 0
Reputation: 30569
From the QLibrary
documentation:
The symbol must be exported as a C function from the library. This means that the function must be wrapped in an
extern "C"
if the library is compiled with a C++ compiler. On Windows you must also explicitly export the function from the DLL using the__declspec(dllexport)
compiler directive
You should add extern "C"
to the declaration and definition of API_Initial
:
extern "C" int API_Initial(char *machineType, int totalLayers, char *fileName)
or enclose it in an extern "C"
block:
extern "C" {
int API_Initial(char *machineType, int totalLayers, char *fileName);
}
C++ has function overloading, but every function in a needs a unique name for the linker to use. To achieve this, names are mangled to encode their signature. This means that int foo(int)
and int foo(double)
have different names, and the linker can distinguish them, but neither are named foo
. One is named ?foo@@YAHH@Z
and the other is named ?foo@@YAHN@Z
(on Windows. Other platforms have different name mangling schemes, but the idea is the same).
This means that when QLibrary
looks for the name API_Initial
it can't find it. It could find the name ?API_Initial@@YAHPEADH0@Z
, but there's no good platform-independent way to derive that name.
Adding extern "C"
to a function declaration disables this name mangling, but precludes function overloading, limits the name to the global namespace, and limits the function's interface to only trivially copyable object types and pointers.
Upvotes: 1
Reputation: 2992
Try
initial function = (initial)lib_3wn->resolve("_API_Initial");
or
initial function = (initial)lib_3wn->resolve("_API_Initial@4");
or
initial function = (initial)lib_3wn->resolve("@API_Initial@4");
depending on calling convention. See this for more info
Upvotes: 0