gpt4 book ai didi

c# - 将方法指针从 C# 传递到 Delphi DLL

转载 作者:行者123 更新时间:2023-11-30 14:03:26 24 4
gpt4 key购买 nike

我在将字符串作为 PChar 传递给 Delphi 构建的 DLL 时遇到了一些问题,感谢 Jens Mühlenhoff 解决了这个问题。

现在我有另一个问题 -

如果 Delphi 声明是常规类型过程,我在传递给 DLL 时成功回调了 c# 方法,但如果 Delphi 声明是方法类型过程,我得到“试图读取或写入 protected 内存”错误。

我试着搜索...

这是Delphi声明

TCallBack = procedure ( s : String) of object;stdcall;

这是C#代码

[DllImport(
"DLLTest.dll",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi,
EntryPoint = "DLL_Test"
)]
public static extern void DLL_Test(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string Location, int AIntValue);

public delegate void MethodCallBackEvent(string s);
public event MethodCallBackEvent Info;

public void GetInfo(string s)
{
MessageBox.Show("Info: " + s);
}

用作

            Info = GetInfo; //or Info = new MethodCallBackEvent(GetInfo);
IntPtr p = Marshal.GetFunctionPointerForDelegate(Info);

DLL_Test(p, "location message", 10);

最佳答案

这是一个工作示例。 DllTest1 正在使用正常的函数回调。 DllTest2 期望回调作为直接的 C# 函数指针(需要在 Delphi 方面进行一些小修改),而 DllTest3 需要一个 Delphi 方法回调指针(需要在 C# 方面进行一些小修改)。

// Delphi
library test;

uses
SysUtils;

{$R *.res}

type
TCallback = procedure (P: PChar); stdcall;
TMethodCallback = procedure (P: PChar) of object; stdcall;

procedure DllTest1(Callback: TCallback; P: PChar; I: Integer); stdcall;
var
S: string;
begin
S := Format('DllTest1 ''%s'' %d', [P, I]);
if Assigned(Callback) then
Callback(PChar(S));
end;

procedure DllTest2(_Callback: Pointer; P: PChar; I: Integer); stdcall;
var
Callback: TMethodCallback absolute _Callback;
S: string;
begin
S := Format('DllTest2 ''%s'' %d', [P, I]);
if Assigned(Callback) then
Callback(PChar(S));
end;

procedure DllTest3(Callback: TMethodCallback; P: PChar; I: Integer); stdcall;
var
S: string;
begin
S := Format('DllTest3 ''%s'' %d', [P, I]);
if Assigned(Callback) then
Callback(PChar(S));
end;

exports
DllTest1,
DllTest2,
DllTest3;

begin
end.

// C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace DllTest
{
class Program
{
public struct Method
{
public IntPtr code;
public IntPtr data;
}
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "DllTest1")]
public static extern void DllTest1(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string s, int i);
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "DllTest2")]
public static extern void DllTest2(IntPtr p, [MarshalAs(UnmanagedType.LPStr)] string s, int i);
[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, EntryPoint = "DllTest3")]
public static extern void DllTest3(Method m, [MarshalAs(UnmanagedType.LPStr)] string s, int i);

public delegate void Callback([MarshalAs(UnmanagedType.LPStr)] string s);
public delegate void MethodCallback(IntPtr self, [MarshalAs(UnmanagedType.LPStr)] string s);
public static void ShowInfo(string s)
{
Console.WriteLine("Info: " + s);
}
public static void ShowMethodInfo(IntPtr self, string s)
{
Console.WriteLine("Info: " + s);
}


static void Main(string[] args)
{
Method m;
Callback info = ShowInfo;
MethodCallback methodInfo = ShowMethodInfo;
IntPtr p = Marshal.GetFunctionPointerForDelegate(info);
IntPtr pm = Marshal.GetFunctionPointerForDelegate(methodInfo);

// function callback example
DllTest1(p, "test", 42);
// method callback example 1
DllTest2(pm, "test", 42);
// method callback example 2
m.code = pm;
m.data = IntPtr.Zero;
DllTest3(m, "test", 42);
}
}
}

关于c# - 将方法指针从 C# 传递到 Delphi DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4153549/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com