C#调用C ++ DLL函数,需要一个双精度数组和一个结构作为输入

时间:2022-03-28 16:57:02

I need to call the following function from an old C++ DLL in my C# code. I can't edit the C++ code and this is all the info I have about that function:

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

LoadMemDouble:


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

功能:uint PASCAL LoadMemDoubleAB(void far * lpobj,double far * lpy,TARHDR far * lptar)

Purpose: Load data into DLL from a passed structure of 64-bit floats. IMPORTANT - any passed arrays, data structures, etc. must be global as the DLL just maintains a pointer back to the array / structure.

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

Arguments:

  • lpobj = Far pointer of prediction data structure;

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

  • lpy = Pointer of double type y value;

    lpy =双精度y值的指针;

  • lptar = Pointer of data header. Note TARHDR was defined as:

    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 field must be set to zero;

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

Returns: 0 or error code.

返回:0或错误代码。

I imported the DLL in C# as follows:

我在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);

I built my structure in C# as follows:

我用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.
        }

Then:

 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);

I have no error message of any kind but it doesn't seems that this is working properly. I am suspecting there is an error in the way I am passing the double array and/or the structure. I am quite new to C# as well and I am stuck on this problem.

我没有任何类型的错误消息,但似乎这没有正常工作。我怀疑我传递双数组和/或结构的方式有错误。我对C#也很陌生,我坚持这个问题。

Only info I could find about this is in German here: http://microsoft.public.de.german.entwickler.dotnet.csharp.narkive.com/g9rTQP1U/c-dll-in-c-nutzen#post9 and its dated from 14 years ago... that's a really old DLL.

我在这里只能找到有关这方面的信息:http://microsoft.public.de.german.entwickler.dotnet.csharp.narkive.com/g9rTQP1U/c-dll-in-c-nutzen#post9及其日期从14年前开始......这是一个非常古老的DLL。

Thanks for your help!

谢谢你的帮助!

1 个解决方案

#1


0  

Yes, as jdweng suggested, the solution is to use a IntPtr for dMemDouble in C#. as follows:

是的,正如jdweng所说,解决方案是在C#中使用IntPtr for dMemDouble。如下:

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

Then:

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

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

Marshal.FreeHGlobal(p);

Now that works nicely. Thanks!

现在这很好用。谢谢!

#1


0  

Yes, as jdweng suggested, the solution is to use a IntPtr for dMemDouble in C#. as follows:

是的,正如jdweng所说,解决方案是在C#中使用IntPtr for dMemDouble。如下:

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

Then:

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

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

Marshal.FreeHGlobal(p);

Now that works nicely. Thanks!

现在这很好用。谢谢!