从c#调用托管c ++ dll函数

时间:2013-02-14 02:52:27

标签: c# c++

这是我的c#main

class Program
{
    static void Main(string[] args)
    {
        int i;
        unsafe
        {
        hdf_call_vars_t ret_vals;

        //IntPtr a ;
        //Marshal.PtrToStructure(a,ret_vals);

        ret_vals.fetch_nav = 1;
        string str = "C:\\DoAT\\a.h5";
        byte[] bytes = Encoding.ASCII.GetBytes(str);

            fixed (byte* p = bytes)
            {
                sbyte* sp = (sbyte*)p;
                //SP is now what you want
                DoAT.atrClass1 cl = new DoAT.atrClass1();

                cl.read_hdf5_file(sp,  ret_vals);

其中c#中的struct是

[StructLayout(LayoutKind.Sequential, Pack = 1)]
/* Returned values from read_hdf5_file */
unsafe struct hdf_call_vars_t {
    public channel_vars p_vars; 
    public channel_vars s_vars; 
    FILE_VERSION file_vers; /* Set in top level sub. used in lower */
    public int fetch_nav; /* Boolean flag */
    public s_line_header_t * n_addr; /* malloc'd address of n data */
    public UInt32 n_lines;
    csdt_file_header_t hdr; 
};

这不编译,说'cl'需要输入指向hdf_call_vars_t的指针。

在我的c ++ managed dll中我有

int atrClass1::read_hdf5_file
    (const char * file_path, /* Path to  file */
     hdf_call_vars_t & ret_vals)

以及

struct hdf_call_vars {
    struct channel_vars p_vars; 
    struct channel_vars s_vars; 
    enum FILE_VERSION file_vers; /* Set in top level sub. used in lower */
    int fetch_n;     
    s_line_header_t * n_addr; /* malloc'd address of  data */
    unsigned int n_lines;
    csdt_file_header_t hdr; 
};
typedef struct hdf_call_vars hdf_call_vars_t;

为什么c#认为指针需要发送到C ++?如果是这样,我如何在c#世界中创建结构的指针?

1 个答案:

答案 0 :(得分:0)

如果您的C ++ DLL是托管的,为什么不将atrClass1标记为托管并避免所有P / Invoke混乱?

public ref class atrClass1
{
public:
    int read_hdf5_file(String^ file_path, hdf_call_vars^% ret_vals)
    {
        ...
    }
};

然后你可以直接从C#中使用它。

当然,您还需要一个托管版本的hdf_call_vars。您还应该使代码更加面向对象(避免使用像当前hdf_call_vars这样的POD类型)。