Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非托管导出和委托_C#_Delphi_Dll_Delphi 7 - Fatal编程技术网

C# 非托管导出和委托

C# 非托管导出和委托,c#,delphi,dll,delphi-7,C#,Delphi,Dll,Delphi 7,我正在使用Robert Giesecke非托管导出创建一个.NET包装DLL,以便在Delphi 7中使用.NET DLL。到目前为止一切正常,但现在我有了一个需要回调/委托的函数 如何做到这一点 我可以只给函数指针指向我的.NET DLL并从那里调用它吗?如果是,它是如何完成的?您可以: 1) 使NET DLL函数返回一个整数,该整数由Delphi 7 DLL使用。不同的返回结果将触发在Delphi7 DLL中调用的各种过程 2) 使其完全原生(从NET转换为Delphi7) 3) 使其完全成

我正在使用Robert Giesecke非托管导出创建一个.NET包装DLL,以便在Delphi 7中使用.NET DLL。到目前为止一切正常,但现在我有了一个需要回调/委托的函数

如何做到这一点

我可以只给函数指针指向我的.NET DLL并从那里调用它吗?如果是,它是如何完成的?

您可以:

1) 使NET DLL函数返回一个整数,该整数由Delphi 7 DLL使用。不同的返回结果将触发在Delphi7 DLL中调用的各种过程

2) 使其完全原生(从NET转换为Delphi7)

3) 使其完全成网(改为完全成网)


4) 如果两者都是DLL,则可以通过非托管DLL调用将本机DLL函数从Delphi导出到NET。

这非常简单。您可以像使用标准p/invoke一样定义委托类型

下面是我能想到的最简单的例子:

C#

Delphi

program Project1;

{$APPTYPE CONSOLE}

type
  TFooDelegate = function: Integer; stdcall;

function Test(foo: TFooDelegate): Integer; stdcall; external 'ClassLibrary1.dll';

function Func: Integer; stdcall;
begin
  Result := 666;
end;

begin
  Writeln(Test(Func));
end.
输出

666 666 C端的默认调用约定是
CallingConvention.Stdcall
,所以我同意这一点。这是显而易见的事情。

找到了答案,这对我帮助很大

基本上,您可以发送指针并调用它

在C侧:

  • 定义代理的签名

    public delegate void LinkCallback(int AValue);
    
  • 创建一个IntPtr变量来存储指针

    public IntPtr Callback;           
    
  • 在获取指针的DLL函数中,将其分配给变量

    Callback = new IntPtr(cb);
    
  • 要调用回调,必须对其进行封送处理

    LinkCallback callback = (LinkCallback)Marshal.GetDelegateForFunctionPointer(ConList[Idx].Callback,typeof(LinkCallback));
    
    callback(10);
    

  • FWIW,如果要创建现有.net DLL的包装器,那么混合模式C++/CLI可能是更好的方法。它至少依赖于官方支持的机制,而不是非托管Dexports提供的魔力。我并不反对UnmanagedExports,因为它确实非常优秀。@DavidHeffernan我很想使用C++/CLI(我有一个这样的版本),但它需要VC 2015 Redist,尽管它只是一个很薄的传递包装器。有没有办法删除该依赖项或静态链接它?根本不需要
    GetDelegateForFunctionPointer
    。这比需要的复杂得多。这确实是完全可能的。为什么要否决我的答案?我提出了答案。哈哈。-第二个人得到-2…你的答案值得投否决票,因为它在很大程度上是不正确的。你说事实上很可能发生的事情是不可能的,最好把错误的陈述去掉。但是,您没有解决问题的关键,即如何将Delphi函数指针传递给C#函数(使用Robert Giesecke的UnmanagedExports导出),然后从C#代码调用该Delphi函数。相反,你提出了很多选择。你可以这样做作为一个评论,但你不能直接回答被问到的问题。谢谢你的回答。这确实比我用的容易多了。
    LinkCallback callback = (LinkCallback)Marshal.GetDelegateForFunctionPointer(ConList[Idx].Callback,typeof(LinkCallback));
    
    callback(10);