在Delphi中实现C DLL

时间:2014-11-06 07:14:38

标签: c++ delphi dll

我正在努力从C dll实现一个函数。它被声明为

int DetectTransactionCode(wchar_t* wi_type, wchar_t* wi_id);

如果已在我的delphi代码中声明并调用它

function DetectTransactionCode (var wi_type, wi_id: PWideChar): Integer;
     cdecl; external 'WiGroupDetect.dll';

procedure TForm20.Button2Click(Sender: TObject);
var witype,wi_id : widestring;
res : integer;
begin
 res := DetectTransactionCode(PWideChar(witype),PWideChar(wi_id));
 showmessage(res.tostring);
 ShowMessage(witype +' & ' +wi_id);
end;

我收到了结果,但是我的witype和wi_id会导致访问违规。

我也尝试过:

Function  DetectTransactionCode (var witype,wi_id :widestring ) : Integer cdecl;
                  external 'WiGroupDetect.dll';

procedure TForm20.Button2Click(Sender: TObject);
var witype,wi_id : widestring;
 res : integer;
begin
 res := DetectTransactionCode(witype,wi_id);
 showmessage(res.tostring);
 ShowMessage(witype +' & ' +wi_id);
end;

我假设两个参数都是参数。第三方提供了以下内容:

成功返回1,取消/失败返回0

注意:阻止呼叫仅在以下时间返回:     1 - 检测到wiCode,     2 - 调用KillDetectionProcess(), 3 - 发生一些错误或故障,或     4 - 最终超时(30分钟)到期。

参数: wi_type成功返回检索到的令牌类型(即QR的“WIQR”);取消/失败时“无”或“无”。 wi_id返回成功检测到的wiCode;取消时取消“取消”;或者有关于失败的其他错误信息(即“错误:......”)。

我已经尝试将参数更改为ansistring,unicodestring但仍然遇到同样的问题。我怀疑它与var参数有关,但不确定如何克服它。任何帮助将不胜感激。

我已经获得了他们的C样本实现

[DllImport("WiGroupDetect.dll", EntryPoint = "DetectTransactionCode", CallingConvention =             CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private static extern int DetectTransactionCode([MarshalAsAttribute(UnmanagedType.LPWStr)]  StringBuilder strWITYPE, [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder strUID);

不确定这是否会改变我的Delphi实现

2 个答案:

答案 0 :(得分:2)

这两个参数的类型为wchar_t*,它是指向16位字符的指针。通常,这意味着指向以UTF-16宽字符结尾的空终止数组的指针。

因此,所呈现的代码的正确翻译是:

function DetectTransactionCode (wi_type, wi_id: PWideChar): Integer;
    cdecl; external 'WiGroupDetect.dll';

您使用了var类型的WideString个参数。这将匹配指向BSTR的参数,这是非常不同的。

我假设cdecl调用约定,这是我遇到的每个C编译器的默认值。如果你有一些额外的信息表明函数是stdcall,那就这样吧。但正如问题所写,这是cdecl

目前尚不清楚数据是如何流动的。两个字符串参数是输入还是输出?是一个在另一个吗?如果要么输出参数,那么您需要一些方法来了解要分配的缓冲区大小。函数不允许您传递缓冲区长度的事实表明数据流入。也就是说,在这种情况下,参数应该是C代码中的const wchar_t*。这里有很多不确定因素。请注意,函数原型并未完全定义函数的语义。

答案 1 :(得分:0)

感谢大卫帮助他们的答案。我设法使用此代码。我知道如果传回的字符串比我提供的字符串长,则会出现错误

function DetectTransactionCode (wi_type, wi_id: pwidechar): Integer;
stdcall; external 'WiGroupDetect.dll';

procedure TForm20.Button2Click(Sender: TObject);
var witype,wi_id :  widestring;
 res : integer;
begin
 setlength(witype,10);
 setlength(wi_id,100);
 res := DetectTransactionCode(pwidechar(witype),pwidechar(wi_id));
 showmessage(res.tostring);
 setlength(witype,pos(#0,witype)-1);
 setlength(wi_id,pos(#0,wi_id)-1);
 ShowMessage(trim(witype) +' & ' +trim(wi_id));
end;