用c#调用delphi函数
本文关键字:函数 delphi 调用 | 更新日期: 2023-09-27 18:15:17
我正在从c#调用dll中的delphi函数。这里是delphi函数签名-
function CALinkDecode(sCode: PWideChar; SubscriberID, MailshotID, LinkID: PDWORD):
PAnsiChar; stdcall;
我是这样称呼它的
string input = "qvoxyetvr7wksss2zbrmr";
int cas, cam, cal;
var errorString = CALinkDecode(input, out cas,
out cam, out cal);
但是当我运行应用程序时,它在delphi函数中评估这个条件为真-
if (sCode = nil) or (Length(sCode) <> 21) or (SubscriberID = nil) or (MailshotID = nil) or (LinkID = nil) then
begin
Result := 'E_INVALIDARG';
end
我只是想知道我是否在传递函数签名的正确数据类型,以及正确的方法是什么。谢谢。
您的直接问题可能是您正在将ANSI文本传递给sCode参数。不幸的是,您省略了p/invoke声明,该声明将使这一点变得清楚。
这很容易解决,但你有更大的问题。这个函数很难调用,因为它的设计不正确。只有当它返回由编译器分配的常量字符串而不是堆分配的字符串时,它才是可行的。您可以强制它使用该签名,如果您:
- 从本地代码导出一个deallocator函数。
- 使用共享堆分配字符串,例如COM堆。
看起来你正在返回字符串形式的COM错误代码。这是反常的。相反,您可以通过返回HRESULT来简化您的工作。
无论如何,要回答这个直接的问题,你像这样声明p/调用:
[DllImport(@"Mylib.dll", CharSet=CharSet.Unicode)]
static extern IntPtr CALinkDecode(
string sCode,
out uint SubscriberID,
out uint MailshotID,
out uint LinkID
);
然后像这样调用
IntPtr retvalptr = CALinkDecode(...);
然后封送指针到字符串
string retval = Marshal.PtrToStringAnsi(retvalptr);
但是请记住,这只能在返回的字符串数据是静态分配的情况下工作。否则,您将有泄漏,或访问违规。
我的主要建议是重新设计界面。不要在字符串中返回错误代码。
一般来说,如果你必须将字符串从Delphi传递到c#,这样做:- 在Delphi代码中声明一个WideString类型的输出参数。这封装了一个COM BSTR。 在托管端声明一个string类型的out形参。用[MarshalAs(UnmanagedType.BStr)]修饰该参数。
请注意,您不能封送WideString返回值给MS工具,因为Delphi使用不同的ABI来返回值。这就是为什么要使用out参数