Reputation: 245
I'm trying to call a statically-linked static method of a C++ class, but I'm getting the VS linker error LNK2019, "unresolved external symbol". Here's the library source:
// in header file
#define DllExport __declspec (dllexport)
class MyClass{
public:
DllExport
static HWND WINAPI myFunc();
};
// in cpp file
DllExport
HWND WINAPI MyClass::myFunc(){ /* create a GUI window that has instance of MyClass set as its property (using ::SetProp) */ }
myFunc is to serve as an entry point for creating objects of MyClass, which resides hidden in the library. Only such static functions can be used to influence the functionality of a MyClass instance (by providing the corresponding HWND). Here's the library consumer:
#define DllImport __declspec(dllimport)
DllImport
HWND WINAPI myFunc();
...
int main(){
HWND hWnd=myFunc();
... // work with the window and attached MyClass instance
}
(I believe) all file linkages are set correctly - originally, myFunc was designed as a standalone function and all worked just fine. I suspect it must be some calling convetion mismatch that makes the linker produce the error on myFunc. Read through multiple articles on this topic, namely
http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
and
https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
but they didn't solve my problem.
Thanks for a suggestion!
Upvotes: 3
Views: 1897
Reputation:
Since your goal is to create static library, the first thing we want to do is eliminate any mention of dllexport/dllimport
. Such specifiers are only used when you actually create a DLL project.
So for lib.h
, we only need this (with some include guards added for good measure):
// lib.h
#ifndef LIB_H
#define LIB_H
class MyClass{
public:
static void myFunc();
};
#endif
The WINAPI
specification is also unnecessary since you're the one calling the method and can just use the default calling convention without ABI issues (though if you do want to use WINAPI
anyway, then you need to include <windows.h>
in your header file).
For lib.cpp
, we only need this:
// lib.cpp
#include <Windows.h>
#include "lib.h"
void MyClass::myFunc(){
::MessageBox(0,"myFunc call!",NULL,0);
}
For main.cpp
in your app
project, we only need this:
// main.cpp
#include <iostream>
#include <D:\staticlink\lib\lib.h>
int main(){
std::cout << "ahoj";
MyClass::myFunc();
char buf[10];
std::cin >> buf;
return 0;
}
I'd recommend configuring your include paths to find lib.h
through your project settings instead of using absolute paths in your source code, but perhaps you can do that later after you get everything working.
After that, if a problem remains, the only thing you should need to ensure is that your app
project is linking against lib.lib
properly (linker settings).
Upvotes: 3
Reputation: 340218
Your import header file should look more like:
#define DllApi __declspec (dllexport)
class MyClass{
public:
DllApi
static HWND WINAPI myFunc();
};
Upvotes: 1