创建c# DLL并从Delphi调用



我想从Delphi中使用第三方dotnet库(只是几个函数),并计划创建一个c# DLL作为接口。我创建了一个简单的演示DLL作为c# (VS 2019/. net 5)的测试,其中包含一个返回整数的函数(稍后,我想添加一个返回字符串的函数)。当从Delphi 10.4调用DLL时,我得到以下错误:

程序入口点Add无法位于动态链接库D:源代码DelphiTestDLLCSharpWin64DebugTestDLLProject.exe

我使用这种技术来创建DLL。

我的c#代码在一个类库中:

using System;
using System.Runtime.InteropServices;
namespace TestDLLForDelphiV2
{
[ComVisible(true)]
[Guid("8F8F51AA-1A66-4689-83EF-CF61ED99EA92")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalc
{
int Add();
}
[ComVisible(true)]
[Guid("BEB943AE-A406-4F55-A9E5-DD3B12F8D17B")]
public class Calc : ICalc
{
private int numberOne = 3;
private int numberTwo = 5;
// Add two integers
[ComVisible(true)]
public int Add()
{
return numberOne + numberTwo;
}         
}
}

Visual Studio项目文件:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Platforms>x64</Platforms>
<EnableComHosting>true</EnableComHosting>
<EnableRegFreeCom>true</EnableRegFreeCom>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<EnableComHosting>true</EnableComHosting>
<EnableRegFreeCom>true</EnableRegFreeCom>
</PropertyGroup>
</Project>
调用DLL的Delphi代码:
unit Main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
ShellApi;
function Add: Integer; stdcall; // cdecl;  NOTE - I tried with both stdcall and cdecl
External 'TestDLLForDelphiV2.comhost.dll';  //NOTE - Also attempted with TestDLLForDelphiV2.dll
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
Memo.Clear;
i := Add;
Memo.Lines.Add(IntToStr(i));
end;
end.

DLL是用。net 5创建的,据我所知,与以前的。net版本一样,regasm.exe不支持。根据上面的文章,我已经使用regsvr32.exe注册了DLL,并且还尝试了RegFree COM选项(在项目文件中使用EnableRegFreeCom标签)。DLL和Delphi应用程序都是64位编译的。任何提示,建设性的帮助等都将不胜感激。

用c++加载。net框架并在其中创建c#对象

gcroot<Calc^> calc = nullptr;
bool __stdcall GetCalc(int& obj)
{
using namespace System::Runtime::InteropServices;
if (calc.operator->() == nullptr)
calc= gcnew Calc();
System::IntPtr p = Marshal::GetIUnknownForObject(calc);
void* q = p.ToPointer();
obj= (int)q;
return true;

}

德尔福:

type
ICalc=interface(IInterface)
['{8F8F51AA-1A66-4689-83EF-CF61ED99EA92}']
function Add: integer; safecall;
end;
procedure test;
type
TFunc=function(var ASrv: IInterface): boolean; stdcall;
var
Lhn    : THandle;
Lfunc  : TFunc;
Lif    : IInterface;
LifCalc: ICalc;
begin
Lhnd  := LoadLibrary(<C++ DllName>);
try
Lfunc := GetProcAdress(Lhnd, 'GetCalc');

Lfunc(Lif);
if Supports(Lif, ICalc, LifCalc) then
ShowMessage(LifCalc.Add.ToString)
else
raise Exception.Create('Error');

finally
FreeLibrary(Lhnd);
end;
end;

c#

namespace TestDLLForDelphiV2
{
[ComVisible(true)]
[Guid("8F8F51AA-1A66-4689-83EF-CF61ED99EA92")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ICalc
{
[return: MarshalAs(UnmanagedType.I4)]
int Add();
}
public class Calc : ICalc
{
private int numberOne = 3;
private int numberTwo = 5;
// Add two integers
public int Add()
{
return numberOne + numberTwo;
}         
}
}

最新更新