one symbol found and for other "unresolved external symbol" - c

In my Visual Studio 2010 there are 2 projects. One is a static lib (mhook 2.3 if someone asks) and the other is a DLL. Both are set to compile as /MT.
mhook project has two functions in its mhook.h:
BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
BOOL Mhook_Unhook(PVOID *ppHookedFunction);
the dll project references the mhook project and uses both Mhook_SetHook and Mhook_Unhook. Same mhook.h is used. When I compile the dll project, I get the following error:
1>hookdll.obj : error LNK2001: unresolved external symbol _Mhook_Unhook
Note, that the linked successfully found the Mhook_SetHook. If I comment out the use of Mhook_Unhook, the program compiles successfully.
Dumpbin suggests that both symbols are present in the static library:
>dumpbin /symbols mhook-test.lib|find "Mhook"
015 00000000 SECT4 notype () External | ?Mhook_SetHook##YAHPAPAXPAX#Z (i
nt __cdecl Mhook_SetHook(void * *,void *))
122 00000000 SECT3B notype () External | ?Mhook_Unhook##YAHPAPAX#Z (int _
_cdecl Mhook_Unhook(void * *))
>
I am lost and confused, please help.

Answer:
I was apparently mixing C++ and C code - the library at hand was in C++ and my program in C.
I had to add extern C around it, as gleaned from this Using C++ library in C code:
#ifdef __cplusplus
extern "C" {
#endif
BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
BOOL Mhook_Unhook(PVOID *ppHookedFunction);
#ifdef __cplusplus
} // extern "C"
#endif
Once I had done it, my symbol exports started to look much better:
C:\Users\MACABRE\Documents\Visual Studio 2010\Projects\luahooker\Debug>dumpbin /
exports mhook.lib
Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file mhook.lib
File Type: LIBRARY
Exports
ordinal name
_Mhook_SetHook
_Mhook_Unhook

Related

Debugging a DLL for C w/Visual Studio 2015

I'm writing a DLL for an existing application. The DLL is designed to interface to commercial software who's functionality can be enhanced by adding a user defined feature with a DLL.
My DLL compiles and the application can utilize the features, but I want to debug it. It is difficult for me to attach to the process and debug when the commercial software is calling the DLL. Instead, I'd like to build separate code to test the DLL.
All the examples I can find w/DLL's are for C# or C++. I can't quite understand how to do this in C. I seem to be stuck at importing the DLL or referencing the library in the linker.
I've inserted:
__declspec(dllimport) int UserDefinedSurface4(USER_DATA *UD, FIXED_DATA4 *FD);
but I get:
LNK2019 unresolved external symbol "__declspec(dllimport) int __cdecl UserDefinedSurface4(struct USER_DATA *,struct FIXED_DATA4 *)" (__imp_?UserDefinedSurface4##YAHPEAUUSER_DATA##PEAUFIXED_DATA4###Z)
Following advice for C# and C++, I've added a path to the DLL in my project using: Properties->Linker->Input->Additional Dependencies with an explicit path: "D:......\mydll.lib" (that seems kind of brittle... is this right or should I use a relative path or ...?)
Furthermore, I also inserted:
#pragma comment(lib, "D:\\...\\mydll.lib")
and I have included the project with the DLL in my references. What's missing?
Your dll import looks fine.
Check the name of the exported function. Good tool for this task is "Dependency Walker". If your dll compiled as C++, function name can be mangled. To prevent name mangling your export definition in DLL project should be:
extern "C" __declspec(dllexport) int UserDefinedSurface4(USER_DATA *UD, FIXED_DATA4 *FD);
In your application specify Linker -> Additional Library Directories to your library directory and in Linker -> Input specify additional dependency mydll.lib. After that check Linker -> Command Line parameter, it should contains:
"mydll.lib" /LIBPATH:"d:\yourlibrarydir\"

LNK2019 (unresolved external symbol) when linking against built dynamic library in QT

I am using QT 5.5.0 within QtCreator to build a C++ application (referenced to as "the application" from now on) which I am trying to link against dynamic link C library ("the library"). All methods which originate from this library cannot be found by the linker when building the application, example output for one method:
error: LNK2019: unresolved external symbol "__declspec(dllimport) int __cdecl rlwe_FFT_CTX_init(struct fft_ctx *)" (__imp_?rlwe_FFT_CTX_init##YAHPAUfft_ctx###Z) referenced in function [...]
The library is imported by the following statement in the .pro file:
LIBS += "-L$$_PRO_FILE_PWD_/../../Libraries/rlwekex/Build/rlwekex/Release/Win32/" -lrlwekex
I expect this to work, since qmake is running fine and the linker will output another error if I change this to a non-existent library name. Both the application and the library are 32 bit.
The .lib and .dll files for the library have been built by myself using Visual Studio 2013. The same header files are used for building the library and as includes inside the application. A compile switch will mark methods as __declspec(dllexport) or __declspec(dllimport) using the following code:
# ifdef RLWEKEX_DLL_EXPORT
# define RLWEKEX_EXPORT __declspec(dllexport)
# else
# define RLWEKEX_EXPORT __declspec(dllimport)
# endif
The macros are correctly evaluated in both the library (export) as well as the application (import). The signature of the example method would be as follows:
RLWEKEX_EXPORT int rlwe_FFT_CTX_init(FFT_CTX *ctx);
Using dumpbin I can verify that the method is actually exported to the .lib - corresponding /HEADERS entry:
Version : 0
Machine : 14C (x86)
TimeDateStamp: 563B4D17 Thu Nov 05 13:35:35 2015
SizeOfData : 0000001F
DLL name : rlwekex.dll
Symbol name : _rlwe_FFT_CTX_init
Type : code
Name type : no prefix
Hint : 2
Name : rlwe_FFT_CTX_init
I have another Visual Studio 2013 project which is a test suite (written in C) for this particular library, which is linking against it just fine! QtCreator and Visual Studio 2013 are running on the same machine and are both using the same compiler toolkit (msvc).
Now of course my question: What could be the reason that I can link against the library in the VS2013 test suite, but not in the QT project? Any help would be appreciated!
C++ mangles names of functions while C does not.
The header file for the library needs to contain, near the beginning of the file, something like:
#ifdef __cplusplus
extern "C" {
#endif
and near the end of the header file
#ifdef __cplusplus
}
#endif
Note: the above lines are between the 'include guards', not to replace them
.

MASM: Accessing to global C variable from assembly

I'm writing a program to convert image and compare the speed of processing data in C and assembly. I have 3 projects:
main project in C
DLL in C to convert image
DLL in ASM to convert image
In C DLL header, I simply wrote:
#ifdef PROJEKTC_EXPORTS
#define PROJEKTC_API __declspec(dllexport)
#else
#define PROJEKTC_API __declspec(dllimport)
#endif
...
extern PROJEKTC_API unsigned int ThreadID;
PROJEKTC_API void __cdecl funkcjaC(void* Args);
and after including this header, I can access variable ThreadID both in main project and C DLL.
The problem starts when I try to do the same in ASM. I tried constructions like extern ASMThreadID:dword in .code block, but it won't work.
The error I got: error LNK2019: unresolved external symbol _ASMThreadID referenced in function _MyProc1
I have a feeling that it's a matter of 1-2 lines of code, but I can't figure out which instruction should I use.
I link the projects by module definition file in ASM and adding ASM.lib file into the Linker->Input of main project.
Do you have any suggestions?
With small help from old posts in asmcommunity.net, I managed to get it working:
In .asm file, before .data segment:
EXTERNDEF C ASMThreadID:DWORD
In .data segment:
ASMThreadID dd 0
In .def file of ASM DLL:
LIBRARY "nameOfProject"
EXPORTS
...
ASMThreadID
In main C program header (like global declaration):
extern __declspec(dllimport) unsigned int ASMThreadID;
Now it works like a charm.
The 'public' declaration sent me to the right way of searching. Thanks for your help, mate!

Which import directive will import a symbol from a DLL and not add a prefix? (Visual Studio)

The short question is: Which directive adds no prefix to an imported symbol?
I have a library that is 100% C (no C++ and not C compiled with a C++ compiler) It's C top to bottom. (I have to mention that because sometimes folks confuse how Visual Studio works when compiling C using the C++ compiler with C using a C compiler.)
The library was compiled with CMAKE and it outputted a DLL with a symbol table that looks like this:
dumpbin.exe /exports mydll.dll
...stuff...
1 0 00001087 mylib_get_x
..etc..
There's a static lib file too.
dumpbin.exe /exports mydll.lib
...stuff...
mylib_get_x
Notice how there are no weird prefixes? (i.e. no imp on the symbols) This makes the DLL extremely useful when trying to import the functions into things like the FFI in LuaJIT and other compilers/environments.
And I have an app that uses "mylib_get_x()"
/* myfile.c */
... stuff ...
int x;
x = mylib_get_x();
The result is: unresolved external symbol _mylib_get_x referenced in function ...
If I prefix the mylib_get_x() with any of these:
__declspec(dllimport)
__cdecl
__stdcall
_cdecl
extern
extern "C" __declspec(dllimport)
<nothing>
It doesn't matter. It won't work. They add prefixes. Which one adds nothing?
When it was compiled, it had __declspec(dllexport) on it, but it's a 3rd party library, so somehow they got it to avoid the extra prefixes.
I can link in the supplied .lib file that was generated. Same result. (see the dumpbin above that shows the symbol table from the .lib file without prefixes) I can create a manual .def file, generate a lib file from it and link to that. Same result.
I would love it if someone could explain what prefixes go with what directive.
Which directive adds no prefix to the symbol?

DLL implicit linking

I cannot implicitly link DLL to C console application.
I use Visual Studio 2008.
I created empty DLL project "Library" which contains only one file main.c:
__declspec(dllexport) int get_value()
{
return 123;
}
I also created empty console project "CallingProgram" with file main.c:
__declspec(dllimport) int get_value();
void main()
{
int result = get_value();
}
I added "Library.lib" to "Linker\Input\Additional Dependencies".
And still I have this error:
error LNK2019: unresolved external symbol __imp__get_value referenced in function _main
I tested created DLL with LoadLibrary/GetProcAddress - it works fine.
I checked Library.dll using DumpBin and it also looks good:
Microsoft (R) COFF/PE Dumper Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file library.dll
File Type: DLL
Section contains the following exports for Library.dll
00000000 characteristics
5340072C time date stamp Sat Apr 05 17:37:48 2014
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00011109 get_value = #ILT+260(_get_value)
Summary
1000 .data
1000 .idata
2000 .rdata
1000 .reloc
1000 .rsrc
4000 .text
10000 .textbss
Please help me understand what is missing!
1 0 00011109 get_value
The symbol does not have its normal decoration. It would normally be _get_value, all cdecl functions get a leading underscore. And using __declspec(dllexport) also provides the __imp_get_value export. It is a function pointer that optimizes the binding.
But that did not happen, you must have used a .def file in your library project. Which renames exported functions. Which is okay, but now your __declspec(dllimport) is incompatible, the DLL no longer exports the __imp_ function pointer. The linker complains because it cannot find it the import library.
Fix this either by removing the .def file from your library project (best) or by deleting the __declspec(dllimport) attribute from the declaration in your exe project. Writing a .h file that declares the exported functions in the DLL is also highly recommended.

Resources