Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to statically link to a DLL function that is exported by an ordinal?

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.

like image 839
c00000fd Avatar asked Jan 27 '26 15:01

c00000fd


1 Answers

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

like image 153
RbMm Avatar answered Jan 29 '26 05:01

RbMm