Tuesday, July 31, 2007

.NET Interop: Delphi for .NET Unmanaged Exports

There are times when you want to interop with .NET by write something in managed code and want to use it in native code but don't want to use COM Interop. A simple feature of Delphi for .NET is Unmanaged Exports. This allows you to export a function from an Assembly for use from native land. I know there have been a lot of articles about this over the years since Delphi for .NET was released but you can't have too many examples. So here is a simple example of creating an Unmanaged Export:

File | New | Delphi for .NET Projects | Library

Note: There are very few cases you want to use Library. Most of the time you want to use Package. Unmanaged Exports is one of the few reasons to use Library

Paste the following code into the .dpr file.


library netlib;

{$UNSAFECODE ON}

uses
SysUtils,
libunit in 'libunit.pas';

procedure Foo;
begin
WriteLn('Foo');
end;

exports
Foo;

end.


File | New | Delphi Projects | VCL Forms Application

Paste the following code into the .dpr file.


program app;

{$APPTYPE CONSOLE}

uses
Windows;

type
TFooProc = procedure; stdcall;

var
FooProc: TFooProc;
LibHandle: THandle;
begin
LibHandle := LoadLibrary(PChar('netlib.dll'));
if LibHandle <> 0 then
begin
try
@FooProc := GetProcAddress(LibHandle, 'Foo');
if @FooProc <> nil then
FooProc;
finally
FreeLibrary(LibHandle);
end;
end;
end.


When you run app.exe it will load the assembly netlib.dll, get the address of the exported function Foo and invoke it where Foo will print out the string 'Foo'.

2 comments:

Joe White said...

We've tried unmanaged exports before, but haven't had much luck passing or returning nontrivial types. I'd love to see some examples of this. For example, is it safe to call a .NET function that returns a string? Will memory management work correctly? Do I just need to declare the Win32 code to expect a WideString return, or is it more exotic than that?

I'd also be very interested to know if it's possible to pass interfaces from Win32 to a .NET function without using COM.

Chris B. said...

Joe,

Good questions. I'll see what I can do in future posts.

Post a Comment