【问题标题】:Problems calling C++ DLLs in Delphi在 Delphi 中调用 C++ DLL 的问题
【发布时间】:2012-07-03 16:44:00
【问题描述】:

我在 delphi 中调用 C++ DLL 时遇到一些问题,DLL 是用 Labview 编写的,但 DLL 语法都是 C++,我认为主要问题是尝试将数据作为动态数组传递给函数double (本质上是一个指针对吗?)

.h头文件中的函数定义为:

int16_t __cdecl NRELIVparExtract(
  double voltageV[], 
  double currentA[], 
  int32_t nDataPoints, 
  uint16_t fitAlgorithim, 
  int16_t *twoOrLessPoints, 
  double *Voc, 
  double *Isc, 
  double *Vmp, 
  double *Imp
);

我试图用来调用它的 delphi 代码是:

public   { Public declarations }
end;

 var
    Function NRELIVparExtract (voltageV, currentA: Array of Double; nDataPoints :Integer;
            fitAlgorithim :Word; Var twoOrLessPoints : SmallInt;
       Voc, Isc, Vmp, Imp : Double): smallint ; CDecl;External IVparExtract_NREL.dll'

废话

procedure TFormMainIVanalysis.ExtractNREL(InputFileName : ShortString);
var
  VoltArray, CurrArray : Array Of double;
  blah
Begin

  NRELresult := NRELIVparExtract(VoltArray,CurrArray,NpointsForFitting, fitAlgorithm,     twoOrLessPoints, LVoc, LISc, LVmpp, LImpp);

当编译器到达我的 delphi .dpr 中的开始行时,我得到不同的访问冲突错误,或者我得到 IVparExtract_NREL.dll 未找到

欢迎任何建议,干杯,布赖恩

【问题讨论】:

  • 函数末尾的双打是指针是不是漏掉了什么?
  • 啊...我们可能已经找到了解决方法。我们将完整路径放在外部之后,就像这样 External 'E:\blah\IVparExtract_NREL.dll' 现在它似乎找到了 DLL 但我们现在只需要安装 NI labview 运行时引擎...
  • 还要注意LabVIEW双打是大端,而Win平台是小端
  • 你的意思是 LabView 双浮点值不兼容 C 双精度/浮点数?
  • 实用程序 'HeadConv'(edn.embarcadero.com/article/26451) 可能会有所帮助。

标签: c delphi labview


【解决方案1】:

C 类型double[]转换为 Delphi 类型array of Double。 Delphi 类型是一个开放数组,它实际上在内部转换为两个参数,一个指向第一个元素的指针,以及一个整数,它比数组中的元素数少一个。大批。相反,您应该像 C 那样做,并将数组“衰减”为一个简单的指针。

C 类型 double* 不会转换为 Delphi 类型 Double。它是一个指针,所以将你的参数类型声明为指针。

这应该给你以下声明:

function NRELIVparExtract(voltageV, currentA: PDouble; nDataPoints: Integer;
    fitAlgorithim: Word; var twoOrLessPoints: SmallInt;
    Voc, Isc, Vmp, Imp: PDouble): SmallInt; cdecl;
    external 'IVparExtract_NREL.dll';

如果您的程序找不到 DLL,那么您应该确保您的 DLL 位于操作系统会查找它的位置,例如您的程序目录或系统路径上的某个位置。 MSDN has the details on the library search order.

【讨论】:

  • 官方翻译double *的方法是把它变成一个var参数,即var Voc, Isc, Vmp, Imp: Double,但是把指针翻译成指针在IMO更容易理解。 +1
  • @Rudy 没有官方方法。如果NULL 是合法值,则需要将参数声明为指针。否则var 是合理的。由于我认为这些是数组,var 没有真正意义,传递指向第一个元素的指针是声明它的正确方法。
  • @david:当然有官方的方式。您对规则是正确的,如果某些东西可以为 NULL 或表示数组,则不应将其声明为 var。但我不认为这些是数组,它们可能是返回值。但正如我所说,我个人更喜欢更接近原版,所以无论如何我都会使用 PDouble。
  • @david: edn.embarcadero.com/article/10281 是官方转换规范。它非常古老,由 Chralie Calvert 在他还在 Borland 时写的,大约在 D6 时间框架 IIRC 左右。 Embarcadero 和 JEDI 的转换仍然按照该规范进行。
  • @Rudy,表示使用var 或适当的指针,具体取决于参数是否可以为空。但我认为默认情况下,在没有更好的知识的情况下,应该使用指针。虽然它可能不是理想的翻译类型,但使用指针永远不会出错
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多