微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将 *& 和 **& 参数从 C# 代码传递给 C++ dll

如何解决如何将 *& 和 **& 参数从 C# 代码传递给 C++ dll

我有 C++ dll 作为下面的标准

函数原型和结构定义

extern "C" int  __declspec(dllexport) DoOPeration(DataStruct *&,DataStructInfo **&);

typedef struct
{
        int   count;
        float CountData;
        bool  flg;
        BYTE* data;
        char   info[100];
}DataStruct;

typedef struct
{
        int   count;
        bool  flg;
        BYTE* data; 
}DataStructInfo;


DoOPeration 函数的实现如下

int __declspec(dllexport) ImageAnalyze(DataStruct *&all,DataStructInfo **&part)
{
    int ret = 0;
    try
    {
          if(all->count == 0)
            return(ERR_ParaMERROR);

          for(cnt = 0 ; cnt < all->count  ; cnt++)
          {
             if(part[cnt]->data== NULL)
                return(ERR_NO_IMAGE);
          } 
    }
    catch(int err)
    {
        return(err);
    }
    catch(...)
    {
        return(-2);
    }
    return(ret);
}

与上面相对应,我在下面添加了 C# 端代码

DLL 导入,结构(类)定义

[DllImport(@"C:\TestDll.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern int DoOperation(ref DataStruct all,ref DataStructInfo[] part);

[StructLayout(LayoutKind.Sequential)]
public class DataStruct
{
        int   count = 0;
        float CountData = 0;
        bool  flg = 0;
        byte[] data = null;
        string   info = 0;
}

[StructLayout(LayoutKind.Sequential)]
public class DataStructInfo 
{
        int   count = 0;
        bool  flg = 0;
        byte[]  data;   
}

// DoOperation function calling

DataStruct alls = new DataStruct(); // set all required parameter
DataStructInfo[] part= new DataStructInfo[3]; // set all required parameter
int ret = DoOperation(ref alls,ref part);

从c#代码调用C++ dll函数后,我观察到了c++ dll中函数参数的值。

  1. 对于参数[alls] 值正确传递
  2. 对于参数 [part] 的值没有正确传递(显示一些垃圾值)

请告诉我有关从 C# 代码传递第二个参数的信息,即 (**&)。

如果我还犯了任何其他错误,请告诉我,以便我可以更正。

注意:我无法更改 C++ dll 代码

解决方法

我通过以下方法得到了解决方案。

C# 端代码

DLL 导入、结构定义

[DllImport(@"C:\TestDll.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern int DoOperation(ref IntPtr all,ref IntPtr[] part);

[StructLayout(LayoutKind.Sequential)]
public struct DataStruct
{
    public int   count { get; set; }
    public float CountData { get; set; }
    public bool  flg { get; set; }
    public IntPtr data { get; set; }
    public string   info { get; set; }
}

[StructLayout(LayoutKind.Sequential)]
public struct DataStructInfo 
{
    public int   count { get; set; }
    public bool  flg { get; set; }
    public IntPtr  data { get; set; }
}

// First parameter
DataStruct alls = new DataStruct(); // set all required parameter
IntPtr intPtrsAll = new IntPtr();
intPtrsAll = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(DataStruct)));
            Marshal.StructureToPtr<DataStruct>(alls,intPtrsAll,false);

// Second parameter
DataStructInfo[] part= new DataStructInfo[3]; // set all required parameter
IntPtr[] intPtrsParts= new IntPtr[part.Length];

for (int i = 0; i < intPtrsParts.Length; i++)
{
    intPtrsParts[i] = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(DataStructInfo)));
    Marshal.StructureToPtr<DataStructInfo>(part[i],intPtrsParts[i],false);
}

int ret = DoOperation(ref intPtrsAll,ref intPtrsParts);


注意:为了在 C# 端设置 byte[] 数据,我使用了 [IntPtr] 和以下方法

byte[] rowData = GetRawBytes(dataHandler); // function to read byte[] data
int size = Marshal.SizeOf(rowData[0]) * rowData.Length;
data = Marshal.AllocHGlobal(size); // IntPtr property of struct's
Marshal.Copy(rowData,data,rowData.Length);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?