Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a .NET DLL from a Win32 process?

What are the options when it comes to using a .NET DLL from a Win32 process? I need to basically use a C# DLL from a Win32 process.

I have a possible solution right now that requires adding the C# DLL to the GAC (using RegAsm.exe), then calling the C# DLL via COM wrapped calls. However that solution is pretty heavy. It requires that the .NET DLL be added to the GAC on all machines that are supposed to run this Win32 process.

Would it be possible to do this without having to call RegAsm prior to being able to use the C# DLL?

like image 749
Zoran Simic Avatar asked Dec 01 '09 01:12

Zoran Simic


People also ask

Does .NET use Win32?

Net is not replacing Win32. Win32 is the OS level interface, and you can think of . Net as a little sub-OS environment or virtual machine that sits on top of Win32. .

How DLL works in. net?

The use of DLLs helps promote modularization of code, code reuse, efficient memory usage, and reduced disk space. So, the operating system and the programs load faster, run faster, and take less disk space on the computer. When a program uses a DLL, an issue that is called dependency may cause the program not to run.

What is a DLL file in c#?

A Dynamic Link library (DLL) is a library that contains functions and codes that can be used by more than one program at a time. Once we have created a DLL file, we can use it in many applications.


1 Answers

You can use registration-free COM with .NET COM components - see here.

Another option is to use C++/CLI as a bridge. People are mostly familiar with using it to wrap unmanaged APIs to expose to managed code, but it actually works both ways - it is possible to compile with /clr, and yet produce a .dll assembly with plain unmanaged exports, which can be called from unmanaged code as usual. Here's a very simple example that exposes System::String::ToUpper that way:

// compile with cl.exe /clr /LD wrapper.cpp ole32.lib

#include <windows.h>

__declspec(dllexport)
wchar_t* ToUpper(const wchar_t* wcs)
{
    System::String^ s = gcnew System::String(wcs);
    array<wchar_t>^ chars = s->ToUpper()->ToCharArray();

    size_t size = chars->Length * 2;
    wchar_t* dst = (wchar_t*)CoTaskMemAlloc(size + 2);
    pin_ptr<wchar_t> src = &chars[0];
    memcpy(dst, src, size);
    dst[chars->Length] = 0;
    return dst;
}

This will produce wrapper.dll - hybrid managed/unmanaged assembly - and an export library wrapper.lib. The latter can be used in a pure native application as follows:

// compile with cl.exe test.cpp ole32.lib wrapper.lib
// note, no /clr

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

wchar_t* ToUpper(const wchar_t* wcs);

int main()
{
    wchar_t* s = ToUpper(L"foo");  
    wprintf(L"%s", s);
    CoTaskMemFree(s);
}

In practice it will load CLR runtime into the calling process (unless it's already loaded there) and dispatch from native code to managed code transparently - all the magic is done by C++/CLI compiler.

like image 183
Pavel Minaev Avatar answered Nov 01 '22 09:11

Pavel Minaev