【问题标题】:C# call to C++ DLL function that requires an array of doubles and a struct as inputC# 调用需要双精度数组和结构作为输入的 C++ DLL 函数
【发布时间】:2017-12-17 11:15:21
【问题描述】:

我需要在我的 C# 代码中从旧的 C++ DLL 调用以下函数。我无法编辑 C++ 代码,这就是我掌握的关于该函数的所有信息:

LoadMemDouble:


函数:uint PASCAL LoadMemDoubleAB(void far* lpobj,double far* lpy,TARHDR far* lptar)

目的:将数据从传递的 64 位结构加载到 DLL 浮动。重要 - 任何传递的数组、数据结构等必须是 全局,因为 DLL 只维护一个指向数组/结构的指针。

参数:

  • lpobj = 预测数据结构的远指针;

  • lpy = double 类型 y 值的指针;

  • lptar = 数据头指针。注意 TARHDR 被定义为:

typedef struct  {  dword   tarnpts;        //total number of data
                   double  tarffp;         //x value of first y data    
                   double  tarflp;         //x value of last y data
                   char    tarxtype;       //data type of x value 
                   char    tarytype;       //data type of y value 
                   uint    tarx;           //1=has x value 0=only y trace 
}TARHDR;

!!tarx 字段必须设置为零;

返回:0 或错误代码。

我在 C# 中导入的 DLL 如下:

[DllImport("plsiqp32.dll", EntryPoint = "LoadMemDouble", SetLastError = true, CharSet = CharSet.None)]
public static extern int dLoadMemDouble(int handleCal, ref double dYvalues, ref DoubleHeader Header);

我在 C# 中构建了如下结构:

public struct DoubleHeader
        {
            public int npts { get; set; }    
            public double FFP { get; set; }  
            public double FLP { get; set; }  
            public byte Xtype { get; set; }   
            public byte YType { get; set; }   
            public int Xtra { get; set; }    //this must be 0.
        }

然后:

 public DoubleHeader myHeader;
 public double[] myYvalues;

 myHeader = new DoubleHeader();

 myHeader.npts = npts;
 myHeader.FFP = FFP;
 myHeader.FLP = FLP;
 myHeader.XType= Xtype;
 myHeader.YType = Ytype;
 myHeader.Xtra = 0;

 myYvalues = dYvalues;

 int loadFromMemory;

 loadFromMemory = dLoadMemDouble(handleCal, ref myYvalues[0], ref myHeader);

我没有任何类型的错误消息,但它似乎无法正常工作。我怀疑我传递双精度数组和/或结构的方式存在错误。我对 C# 也很陌生,我被这个问题困住了。

我能找到的只有德语的信息:http://microsoft.public.de.german.entwickler.dotnet.csharp.narkive.com/g9rTQP1U/c-dll-in-c-nutzen#post9 它的历史可以追溯到 14 年前...这是一个非常古老的 DLL。

感谢您的帮助!

【问题讨论】:

  • 我的函数使用Windows参数列表还是C语言参数列表?我会在 c# 中使用 IntPtr 作为指针。 IntPtr 是 4 个字节,相当于 c# Int 代码可能看起来像是在工作。我还会将返回参数设为 uint 而不是 int,以便与 d​​ll 相同。

标签: c# c++ arrays pointers dll


【解决方案1】:

是的,正如 jdweng 建议的那样,解决方案是在 C# 中为 dMemDouble 使用 IntPtr。 如下:

[DllImport("plsiqp32.dll", EntryPoint = "LoadMemDouble", SetLastError = true, CharSet = CharSet.None)]
public static extern uint dLoadMemDouble(int handleCal, IntPtr dYvalues, ref DoubleHeader Header); 

然后:

IntPtr p = Marshal.AllocCoTaskMem(sizeof(double) * myYvalues.Length);
            Marshal.Copy(myYvalues, 0, p, myYvalues.Length);

loadFromMemory = dLoadMemDouble(handleCal, p, ref myHeader);

Marshal.FreeHGlobal(p);

现在效果很好。 谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-13
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    相关资源
    最近更新 更多