我正在使用" Unmanaged Exports"库从c#类库中导出函数。对于具有简单签名的基本功能,这非常有用。现在我想导出一个我的Delphi应用程序想要使用的C#对象。以下代码编译:
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)]
public class Sample
{
public string Text
{
[return: MarshalAs(UnmanagedType.BStr)]
get;
[param: MarshalAs(UnmanagedType.BStr)]
set;
}
[return: MarshalAs(UnmanagedType.BStr)]
public string TestMethod()
{
return Text + "...";
}
}
static class UnmanagedExports
{
[DllExport(CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.IDispatch)]
static Object CreateSampleInstance()
{
try
{
return new Sample { Text = "xy" };
}
catch (Exception ex)
{
return null;
}
}
}
在我的Delphi应用程序中,我想通过以下代码加载dll:
function CreateSampleInstance(): IDispatch; stdcall; external 'UnmanagedExports.dll';
procedure TForm3.Button2Click(Sender: TObject);
var
disp: IDispatch;
variant: OleVariant;
begin
CoInitialize(0);
disp := CreateSampleInstance();
variant := disp;
ShowMessage(variant.TestMethod());
end;
我在Delphi-Code中得到一个空指针异常。我的签名肯定有问题。任何人都知道如何使这个工作?
答案 0 :(得分:3)
更精确地遵循示例here(避免使用IDispatch /双接口),它可以工作:
C#
public void Configure(IApplicationBuilder app)
{
// basic stuff
var config = services.GetService<IConfiguration>();
string route = config.GetValue<string>("Path");
app.UseMvc(routes => {
routes.MapRoute("someName", route, new { controller = "myController", action = "myAction"});
});
}
的Delphi /拉扎勒斯
using RGiesecke.DllExport;
using System;
using System.Runtime.InteropServices;
namespace MyLibrary
{
[ComVisible(true)]
[Guid("8871C5E0-B296-4AB8-AEE7-F2553BACB730"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISample
{
[return: MarshalAs(UnmanagedType.BStr)]
string GetText();
void SetText([MarshalAs(UnmanagedType.BStr)]string value);
[return: MarshalAs(UnmanagedType.BStr)]
string TestMethod();
}
public class Sample : ISample
{
public string Text { get; set; }
public string GetText()
{
return Text;
}
public void SetText(string value)
{
Text = value;
}
public string TestMethod()
{
return Text + "...";
}
}
public static class UnmanagedExports
{
[DllExport(CallingConvention = CallingConvention.StdCall)]
public static void CreateSampleInstance([MarshalAs(UnmanagedType.Interface)] out ISample instance)
{
instance = null;
try
{
instance = new Sample { Text = "Hello, world" };
}
catch
{
}
}
}
}