C# P/Invoked 来自 BPL 的函数 returns 指向 Delphi 记录的相同指针,无论输入如何
C# P/Invoked function from BPL returns same pointer to Delphi record regardless of input
我正在尝试使用来自国外 BPL 包的函数,但我无权访问其代码。
虽然我在 Delphi 中取得了成功,但在 C# 中我仍然得到相同的值,无论输入如何。
BPL 在 Delphi
中的外部使用
type
PRecord = ^TRecord;
TRecord = packed record
S: string;
LW: LongWord;
end;
function GetValue(W : Word) : PRecord; external 'package.bpl' name '@Unit@Function$qqrus';
调用 GetValue()
不同的输入 returns 不同的记录,这是正确的。
BPL 在 C# 中的外部使用
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TRecord
{
public string S;
public int LW;
}
[DllImport("package.bpl", EntryPoint = "@Unit@Function$qqrus", CharSet = CharSet.Unicode)]
static extern IntPtr GetValue(ushort number);
public static TRecord GetDelphiValue(ushort number)
{
var ptr = GetValue(number);
return (TRecord) Marshal.PtrToStructure(ptr, typeof(TRecord))
}
使用不同的输入调用 GetDelphiValue()
总是 returns 相同的指针和结构。
我错过了什么?
function GetValue(W : Word) : PRecord;
external 'package.bpl' name '@Unit@Function$qqrus';
此函数使用Delphi的默认调用约定,即register
。其他工具不支持此功能,因此无法从您的 C# 代码调用此函数。
您需要在 C# 代码和 Delphi 程序包之间放置一个 Delphi DLL。 Delphi DLL 将能够调用 register
调用约定函数,并且可以导出具有 stdcall
调用约定的函数供您的 C# 代码调用。
此外,您还有机会解决因使用 Delphi string
类型而引起的任何潜在问题,该类型也是 Delphi.[=17 私有的=]
就其价值而言,我非常怀疑该函数是否确实 return 指向记录的指针。我认为这更有可能是一个将记录作为 var
或 out
参数的过程。而且我确实认为很可能存在与该字符串的生命周期相关的问题。实际上,您不能指望使用没有关于其接口信息的二进制模块。
我正在尝试使用来自国外 BPL 包的函数,但我无权访问其代码。
虽然我在 Delphi 中取得了成功,但在 C# 中我仍然得到相同的值,无论输入如何。
BPL 在 Delphi
中的外部使用type
PRecord = ^TRecord;
TRecord = packed record
S: string;
LW: LongWord;
end;
function GetValue(W : Word) : PRecord; external 'package.bpl' name '@Unit@Function$qqrus';
调用 GetValue()
不同的输入 returns 不同的记录,这是正确的。
BPL 在 C# 中的外部使用
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TRecord
{
public string S;
public int LW;
}
[DllImport("package.bpl", EntryPoint = "@Unit@Function$qqrus", CharSet = CharSet.Unicode)]
static extern IntPtr GetValue(ushort number);
public static TRecord GetDelphiValue(ushort number)
{
var ptr = GetValue(number);
return (TRecord) Marshal.PtrToStructure(ptr, typeof(TRecord))
}
使用不同的输入调用 GetDelphiValue()
总是 returns 相同的指针和结构。
我错过了什么?
function GetValue(W : Word) : PRecord;
external 'package.bpl' name '@Unit@Function$qqrus';
此函数使用Delphi的默认调用约定,即register
。其他工具不支持此功能,因此无法从您的 C# 代码调用此函数。
您需要在 C# 代码和 Delphi 程序包之间放置一个 Delphi DLL。 Delphi DLL 将能够调用 register
调用约定函数,并且可以导出具有 stdcall
调用约定的函数供您的 C# 代码调用。
此外,您还有机会解决因使用 Delphi string
类型而引起的任何潜在问题,该类型也是 Delphi.[=17 私有的=]
就其价值而言,我非常怀疑该函数是否确实 return 指向记录的指针。我认为这更有可能是一个将记录作为 var
或 out
参数的过程。而且我确实认为很可能存在与该字符串的生命周期相关的问题。实际上,您不能指望使用没有关于其接口信息的二进制模块。