【问题标题】:C++ DLL function used in Delphi7Delphi7中使用的C++ DLL函数
【发布时间】:2017-09-09 10:05:30
【问题描述】:

我想在我的 delphi 7 项目中使用 c++ DLL。我在我的 delphi7 项目中成功调用了 DLL 的一个函数,但在另一个参数为 stringbuilder 的函数中出现错误。 C++函数细节如下。(我从dll的头文件中得到)

WN_COMM_ERR WINAPI MYFUNCTION(WN_COMM_HANDLE handle, const char *command, char *answer, unsigned long maxlen, unsigned long timeout_ms, WN_ANSWER_TYPE *type);

而且答案类型是枚举类型:-

 typedef enum {
    WN_ANSWER_ACK = '>',        // An OK frame was received
    WN_ANSWER_NACK = '!',       // An ERR frame was received
    WN_ANSWER_TOUT = 0,         // Command timed out before an answer could be received
}WN_ANSWER_TYPE;

我已经在 c# 代码中成功调用了相同的函数并且它正在工作。但我不知道如何在 delphi7 上调用它,因为答案参数是 stringbuilder 类型,而在 delphi7 中它们不是任何 stringbuilder 类型的东西。我尝试使用 Pansichar,string,pchar 但未在答案类型变量中获得值:-

C# 声明:工作

    [DllImport("wn_comm.dll", CharSet = CharSet.Unicode)]
    public static extern UInt32 MYFUNCTION(IntPtr handle, string command, StringBuilder answer, UInt32 maxlen, UInt32 timeout_ms, ref Int32 answer_type);

调用 C# 函数:工作

WriteNowWrapper.MYFUNCTION(this.comm_handle, command, sbAnswer, (uint)sbAnswer.Capacity, Timeout, ref answerType)

当我从我的 c# 应用程序调用上面时,我已成功接收 answertype 和 sbanswer 变量值。

Delphi7 声明:不工作

function MYFUNCTION  (handle:Longint; command:string;var answer:PAnsichar; maxlen:integer; Timeout:integer; VAR answretype:INTEGER) : longint; stdcall; external 'wn_comm.dll';

Delphi7调用函数:不工作

   MYFUNCTION(self.comm_Handle,command,answer,2,Timeout,answerType)

当我从 delphi7 应用程序调用 MYFUNCTION 时。它成功执行并更新了作为整数类型参数的 answertype 中的值,但在 answer 变量中我变得空白。

谁能帮助我我做错了什么?

【问题讨论】:

标签: c# c++ delphi dll type-conversion


【解决方案1】:

您的 Delphi 函数声明不正确。你不能使用 string 这是一个原生的 Delphi 类型。并且 answer 参数不是 var 参数。

声明应该是:

function MYFUNCTION(
    handle: Integer; 
    command: PAnsichar;
    answer: PAnsichar; 
    maxlen: Cardinal; 
    timeout_ms: Cardinal; 
    out answer_type: Integer
): Cardinal; stdcall; external 'wn_comm.dll';

您的问题中缺少的细节是分配answer 的部分。您显然在 C# 代码中做到了这一点。看起来像这样:

StringBuilder sbAnswer = new StringBuilder(256);

我已经猜到要为容量使用什么值。在您的 Delphi 调用代码中,您需要类似的东西。

var
  handle: Integer; 
  command: AnsiString;
  answer: AnsiString;    
  timeout_ms: Integer; 
  answer_type: Integer;
  err: Integer;
....
handle := ...;
command := ...;
SetLength(answer, 256);
timeout_ms := ...;
err := MYFUNCTION(
    handle, 
    PAnsiChar(command), 
    PAnsiChar(answer), 
    Length(answer),
    timeout_ms,
    answer_type
);

【讨论】:

  • 选民愿意解释一下,还是这只是盲目的报复?
【解决方案2】:

类型 如果无法访问 DLL,就很难说出哪里出了问题。但是先试试这个

function WN_ExeCommandA  (handle:Longint; command: PAnsichar;var answer:PAnsichar; maxlen:integer; Timeout:integer; VAR answretype:INTEGER) : longint; stdcall; external 'wn_comm.dll';

如果我能看到 WN_ANSWER_TYPE 的 c++ 定义,我可以为您提供更多帮助。

【讨论】:

  • it just a enum typedef enum { WN_ANSWER_ACK = '>', // 收到 OK 帧 WN_ANSWER_NACK = '!', // 收到 ERR 帧 WN_ANSWER_TOUT = 0, // 命令超时在收到答复之前 }WN_ANSWER_TYPE;
  • @DavidHeffernan 那么什么是对的?你能解释一下我应该使用什么类型的数据类型吗?
  • @Pri 我在回答中解释了
  • @PriyankaMehta:var 是错误的。它只是answer: PAnsiCharPAnsiChar 已经是一个指针 (char *)。使用var 会增加一层间接性,这是错误的。我已经发布了,但又一次:rvelthuis.de/articles/articles-convert.html#params .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-30
  • 2020-11-06
  • 2010-10-07
相关资源
最近更新 更多