Home > Blockchain >  Can't call function from .dll created in C
Can't call function from .dll created in C

Time:11-12

I'm able to call function from DLL created in C (.c file), but i can't do it from DLL created in C (.cpp file). I want to find out why it doesn't work in .cpp file.

I'm trying to call function printword() from a simple DLL, created with Visual Studio 2022:

// FILE: dllmain.cpp

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


__declspec(dllexport) void printword() {
    std::cout << "word" << std::endl;    //with printf() doesn't work too
}

And when i call function the way like this:

int main() {

    HMODULE dll;
    if ((dll = LoadLibrary(L"D:\\Visual Studio projects\\Dll1\\x64\\Debug\\Dll1.dll")) == NULL) {
        return GetLastError();
    }

    FARPROC func;
    if ((func = GetProcAddress(dll, "printword")) == NULL) {
        return GetLastError();
    }

    func();

    return 0;
}

GetProcAddress throws error ERROR_PROC_NOT_FOUND

But if i create DLL in file with .c suffix printword() function calls correctly (with same code above):

// FILE: dllmain.c

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


__declspec(dllexport) void printword() {
    printf("word\n");
}

CodePudding user response:

Review and try the recommendations from this article: https://learn.microsoft.com/sr-cyrl-rs/cpp/build/exporting-cpp-functions-for-use-in-c-language-executables?view=msvc-170

Example

// MyCFuncs.h
extern "C" __declspec( dllexport ) int MyFunc(long parm1);

Key part being extern "C"

[I accidentally posted the link for importing instead of exporting earlier - corrected for the export article]

CodePudding user response:

The exported function's name will get mangled when the DLL is compiled. You must use the mangled name in GetProcAddress() in order for it to work. For example, the mangled name in MSVC is:

GetProcAddress(dll, "?printword@@YAXXZ");

Or, you could add this to the function's body to tell the compiler not to mangle it:

__declspec(dllexport) void printword() {
    #pragma comment(linker, "/EXPORT:" __FUNCTION__"=" __FUNCDNAME__)
    printf("word\n");
}

Alternatively, adding extern "C" will also solve the problem.

  • Related