Say, if a DLL has a function:
int TestFunc01(int v)
{
WCHAR buff[256];
::StringCchPrintf(buff, _countof(buff), L"You passed a value of %d", v);
return ::MessageBox(NULL, buff, L"Test Dll Message", MB_OK | MB_ICONINFORMATION);
}
that is exported by its ordinal value only (the following is a .def file):
LIBRARY DllName
EXPORTS
TestFunc01 @1 NONAME
So now when I want to statically link to that function from another module, I'd do the following if the function was exported by its name:
extern "C" __declspec(dllimport) int TestFunc01(int v);
int _tmain(int argc, _TCHAR* argv[])
{
TestFunc01(123);
}
But how do I statically link to it only by its ordinal value?
PS. I'm using a Visual Studio C++ compiler & linker.
But how do I statically link to it only by its ordinal value?
absolute the same way, when function exported by name - no any difference. in both case you need 2 things - correct declaration of the function:
extern "C" __declspec(dllimport) int /*calling convention*/ TestFunc01(int v);
and lib file, included to linker input.
when you include somename.def file to visual studio project, it automatically add /def:"somename.def" option to linker (otherwise you need manual add this option). generated lib file will be containing __imp_*TestFunc01* symbol - in place * will be different decoration based on c or c++ symbol and calling convention, in case x86.
from another side, when you call function, with __declspec(dllimport) attribute. compiler (CL) will be generate call [__imp_*TestFunc01*] - so reference to __imp_*TestFunc01* symbol (again * in place actual decoration). linker will be search for __imp_*TestFunc01* symbol and found it in lib file.
the NONAME option does not matter for this process - this this only affects how it will be formed IAT/INT entry for this function in PE (will be it imported by name or ordinal)
note that if we separate generate lib file from def file only, by link.exe /lib /def:somename.def - the linker will be have not correct declarations for exported functions (def file containing name only without calling convention and c or c++ name) - so it always will be considered symbols as extern "C" and __cdecl
in concrete case visible that in dll function implemented as int TestFunc01(int v) - so without extern "C" - as result in lib file will be symbol like __imp_?TestFunc01@@YAHH@Z (i assume __cdecl and x86), but in another module function used with extern "C" - so linker will be search for __imp__TestFunc01 and of course not found it, because it not exist in lib file. because this, when we export/import some symbol - it must be equal declared for both modules. the best declare it in separate .h file with explicit calling convention
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With