如何将结构指针从c#传递给win32 DLL

时间:2015-02-27 11:59:19

标签: c# c++ dll struct bytearray

我想将字节数组从C#传递给win32 DLL,用于c ++中的某些进程!

我的c ++代码

    typedef struct
    {
        int length;
         unsigned char value[10000000];
    } wavfile;

    extern "C" __declspec(dllexport) int insert_In_Table(wavfile *w)
   {

    hashing HS( w->value , (unsigned int)w->length);

        return HS.insertIn_hashTable();
    }

和我的C#

[DllImport("HashCplusDll.dll" , CallingConvention=CallingConvention.Cdecl)]
public static extern int insert_In_Table(ref Wavfile sample);
public static int recordNumber_old = 0;

public struct Wavfile
{

    public int length;
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 10000000)]
    public byte[] value;
}

public void button1_Click(object sender, EventArgs e)
{
    // open file dialog 
    OpenFileDialog open = new OpenFileDialog();
    open.Filter = "All files (*.*)|*.*"; 
    if (open.ShowDialog() == DialogResult.OK)
    {

        string location = open.FileName;
        byte[] array = System.IO.File.ReadAllBytes(location);
        textBox1.Text = location;

        Wavfile pass = new Wavfile();
        pass.value = array;
        pass.length = array.Length;
        int numberOfRow = insert_In_Table(ref pass);
    }

但我有这个错误

  

发生了'System.TypeLoadException'类型的第一次机会异常   在WindowsFormsApplication1.exe中

     

附加信息:无法封送类型的字段“值”   'Wavfile':无效的托管/非托管类型组合(数组字段   必须与ByValArray或SafeArray配对。

     

如果存在此异常的处理程序,则程序可能是安全的   继续进行。

我尝试了一些解决方案,例如out而不是ref,但又无法运行应用。

我应该做什么?

2 个答案:

答案 0 :(得分:1)

由于MarshallAs的meta属性,它正在抱怨。您需要将其更改为ByValArray。

而不是UnmanagedType.LPArray使用UnmanagedType.ByValArray

答案 1 :(得分:0)

我通过将值字段更改为指针

来解决它

C ++

typedef struct
{
    int length;
    unsigned char* value;
} wavfile;

extern "C" __declspec(dllexport) int insert_In_Table(wavfile *w)
{

    hashing HS( w->value , (unsigned int)w->length);

    return HS.insertIn_hashTable();
} 

C#

[DllImport("C:\\...\\HashCplusDll.dll", CallingConvention= CallingConvention.Cdecl)]
        public static extern int insert_In_Table(ref Wavfile sample);
        public static int recordNumber_old = 0;
        //StructLayout(LayoutKind.Sequential)]
        public struct Wavfile
        {

            public int length;
            public IntPtr value;
        }

        public void button1_Click(object sender, EventArgs e)
        {
            // open file dialog 
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "All files (*.*)|*.*";
            if (open.ShowDialog() == DialogResult.OK)
            {

                string location = open.FileName;
                byte[] array = System.IO.File.ReadAllBytes(location);
                textBox1.Text = location;

                Wavfile pass = new Wavfile();

                pass.length = array.Length;
                pass.value = Marshal.AllocHGlobal(array.Length);
                Marshal.Copy(array, 0, pass.value, array.Length);
                // Call unmanaged code
                int numberOfRow = insert_In_Table(ref pass);
}