0

I'm new to c and c++. I'm a somewhat familiar with higher-level programming languages (python, c#). Just want to familiarize myself with low-level stuff (c, assembly etc). This is my attempt to compile dll that exports a function that should print string to the console. Unfortunately nothing is printed to the console.

#include <windows.h>
#include <stdio.h>

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 CALLBACK say_hello(void)
{
    printf("Hello world!");
}

then I run dll with rundll32.exe .\say_hello.dll,say_hello. It produces no errors, but also doesn't print the expected string.

FAMO4S
  • 17
  • 4
  • FYI, since you are new to C++, be aware that C++ allows function and operator overloading. There may be "name mangling" performed in order for C language to use C++ functions. This may make interfacing with DLLs more difficult. – Thomas Matthews May 18 '23 at 23:32
  • 1
    printf() only works in a console mode app, rundll32.exe is not. Signature is [wrong too](https://stackoverflow.com/questions/67813092/how-to-create-a-native-c-dll-that-i-can-run-with-rundll32-exe-without-specifyi). Consider, say, MessageBox(). – Hans Passant May 18 '23 at 23:33
  • 1
    rundll is also deprecated. Better to write your own stub exe to test your dll. This also makes sure you understand DLL usage from the consuming side. – Paul Dempsey May 18 '23 at 23:35
  • Your `say_hello()` function does not match the signature that rundll32 expects, so your code will invoke *undefined behavior* if run by rundll32. See [How to use Rundll32 to execute DLL Function?](https://stackoverflow.com/questions/3207365/). That's assuming rundll32 even finds your export at all, as it may be named-mangled when compiled in C++. To avoid that Wrap the declaration in `extern "C"`, or compile with a `.def` file. – Remy Lebeau May 18 '23 at 23:55
  • The MessageBox indeed worked, even without changing the signature. MSDN has this [code snippet](https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=msvc-170) `__declspec(dllexport) void __cdecl Function1(void);` on its webpage with `void` as an argument. What's the difference between `CALLBACK` and `__cdecl`? I couldn't find anything about the `CALLBACK` keyword. @HansPassant – FAMO4S May 18 '23 at 23:59
  • Also thanks everyone for the your input! Much appreciated! – FAMO4S May 19 '23 at 00:00
  • 1
    @indigoer the Microsoft snippet you refer to is not a rundll32 example. Your function MUST be like `void CALLBACK Function1(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)` instead for rundll32 to call it correctly. As for `CALLBACK`, it is an alias for `__stdcall` on Windows – Remy Lebeau May 19 '23 at 00:01
  • @indigoer That export example you keep referring to is NOT VALID FOR USE WITH RUNDLL32! Read this documentation instead: [INFO: Windows Rundll and Rundll32 Interface](https://web.archive.org/web/20150109234931/http://support.microsoft.com/kb/164787) (it is old, and no longer available on MSDN, but it still applies) – Remy Lebeau May 19 '23 at 00:05

0 Answers0