#include <Windows.h>
#include <cstdio>
#include <memory> // for unique_ptr.
#include <type_traits> // for remove_pointer.
int main()
{
auto hm1 = ::LoadLibraryW(LR"unko(C:\Projects\TestDll\Debug\TestDll.dll)unko");
if ( hm1 == nullptr )
{
std::printf("load1 failed\n");
return ~0;
}
std::unique_ptr<std::remove_pointer<decltype(hm1)>::type, void (*)(decltype(hm1))>
disposer1(hm1, [](decltype(hm1) h){ ::FreeLibrary(h); });
std::printf("dll1 okay\n");
auto hm2 = ::LoadLibraryW(LR"unko(C:\Projects\TestDll\TestDll.dll)unko");
if ( hm2 == nullptr )
{
std::printf("load2 failed\n");
return ~0;
}
std::unique_ptr<std::remove_pointer<decltype(hm2)>::type, void (*)(decltype(hm2))>
disposer2(hm2, [](decltype(hm2) h){ ::FreeLibrary(h); });
std::printf("dll2 okay\n");
auto *pf1 = reinterpret_cast<long long (__stdcall *)()>(::GetProcAddress(hm1, "f"));
if ( pf1 == nullptr )
{
std::printf("getprocaddress1 failed\n");
return ~0;
}
auto *pf2 = reinterpret_cast<long long (__stdcall *)()>(::GetProcAddress(hm2, "f"));
if ( pf2 == nullptr )
{
std::printf("getprocaddress2 failed\n");
return ~0;
}
std::printf("%lld\n", pf1()); // 1
std::printf("%lld\n", pf1()); // 2
std::printf("%lld\n", pf1()); // 3
std::printf("%lld\n", pf2());; // 1
std::printf("%lld\n", pf2());; // 2
std::printf("%lld\n", pf2());; // 3
}
/*
TestDll.dll
#include <Windows.h>
namespace unko
{
long long g_count;
}
LONGLONG __stdcall f()
{
return ++unko::g_count;
}
*/
CiNpbmNsdWRlIDxXaW5kb3dzLmg+CgojaW5jbHVkZSA8Y3N0ZGlvPgojaW5jbHVkZSA8bWVtb3J5PiAgICAJLy8gZm9yIHVuaXF1ZV9wdHIuCiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4JLy8gZm9yIHJlbW92ZV9wb2ludGVyLgoKaW50IG1haW4oKQp7CglhdXRvIGhtMSA9IDo6TG9hZExpYnJhcnlXKExSInVua28oQzpcUHJvamVjdHNcVGVzdERsbFxEZWJ1Z1xUZXN0RGxsLmRsbCl1bmtvIik7CglpZiAoIGhtMSA9PSBudWxscHRyICkKCXsKCQlzdGQ6OnByaW50ZigibG9hZDEgZmFpbGVkXG4iKTsKCQlyZXR1cm4gfjA7Cgl9CglzdGQ6OnVuaXF1ZV9wdHI8c3RkOjpyZW1vdmVfcG9pbnRlcjxkZWNsdHlwZShobTEpPjo6dHlwZSwgdm9pZCAoKikoZGVjbHR5cGUoaG0xKSk+CgkJZGlzcG9zZXIxKGhtMSwgW10oZGVjbHR5cGUoaG0xKSBoKXsgOjpGcmVlTGlicmFyeShoKTsgfSk7CglzdGQ6OnByaW50ZigiZGxsMSBva2F5XG4iKTsKCglhdXRvIGhtMiA9IDo6TG9hZExpYnJhcnlXKExSInVua28oQzpcUHJvamVjdHNcVGVzdERsbFxUZXN0RGxsLmRsbCl1bmtvIik7CglpZiAoIGhtMiA9PSBudWxscHRyICkKCXsKCQlzdGQ6OnByaW50ZigibG9hZDIgZmFpbGVkXG4iKTsKCQlyZXR1cm4gfjA7Cgl9CgoJc3RkOjp1bmlxdWVfcHRyPHN0ZDo6cmVtb3ZlX3BvaW50ZXI8ZGVjbHR5cGUoaG0yKT46OnR5cGUsIHZvaWQgKCopKGRlY2x0eXBlKGhtMikpPgoJCWRpc3Bvc2VyMihobTIsIFtdKGRlY2x0eXBlKGhtMikgaCl7IDo6RnJlZUxpYnJhcnkoaCk7IH0pOwoJc3RkOjpwcmludGYoImRsbDIgb2theVxuIik7CgkKCWF1dG8gKnBmMSA9IHJlaW50ZXJwcmV0X2Nhc3Q8bG9uZyBsb25nIChfX3N0ZGNhbGwgKikoKT4oOjpHZXRQcm9jQWRkcmVzcyhobTEsICJmIikpOwoJaWYgKCBwZjEgPT0gbnVsbHB0ciApCgl7CgkJc3RkOjpwcmludGYoImdldHByb2NhZGRyZXNzMSBmYWlsZWRcbiIpOwoJCXJldHVybiB+MDsKCX0KCQoJYXV0byAqcGYyID0gcmVpbnRlcnByZXRfY2FzdDxsb25nIGxvbmcgKF9fc3RkY2FsbCAqKSgpPig6OkdldFByb2NBZGRyZXNzKGhtMiwgImYiKSk7CglpZiAoIHBmMiA9PSBudWxscHRyICkKCXsKCQlzdGQ6OnByaW50ZigiZ2V0cHJvY2FkZHJlc3MyIGZhaWxlZFxuIik7CgkJcmV0dXJuIH4wOwoJfQoKCXN0ZDo6cHJpbnRmKCIlbGxkXG4iLCBwZjEoKSk7IC8vIDEKCXN0ZDo6cHJpbnRmKCIlbGxkXG4iLCBwZjEoKSk7IC8vIDIKCXN0ZDo6cHJpbnRmKCIlbGxkXG4iLCBwZjEoKSk7IC8vIDMKCglzdGQ6OnByaW50ZigiJWxsZFxuIiwgcGYyKCkpOzsgLy8gMQoJc3RkOjpwcmludGYoIiVsbGRcbiIsIHBmMigpKTs7IC8vIDIKCXN0ZDo6cHJpbnRmKCIlbGxkXG4iLCBwZjIoKSk7OyAvLyAzCn0KCi8qCiBUZXN0RGxsLmRsbAoKI2luY2x1ZGUgPFdpbmRvd3MuaD4KCm5hbWVzcGFjZSB1bmtvCnsKCWxvbmcgbG9uZyBnX2NvdW50Owp9CgpMT05HTE9ORyBfX3N0ZGNhbGwgZigpCnsKCXJldHVybiArK3Vua286OmdfY291bnQ7Cn0KCgoqLwo=