2015-02-27 2 views
1

Я хочу передать массив байтов из C# в win32 DLL для некоторых процессов в C++!Как передать указатель структуры из C# в win32 DLL

мой 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); 
    } 

но я эта ошибка

A first chance exception of type 'System.TypeLoadException' occurred in WindowsFormsApplication1.exe

Additional information: Cannot marshal field 'value' of type 'Wavfile': Invalid managed/unmanaged type combination (Array fields must be paired with ByValArray or SafeArray).

If there is a handler for this exception, the program may be safely continued.

Стараюсь какое-то решение, как в качестве out вместо ref но опять же может» t запуск приложения.

Что я должен делать?

+1

Ваша C# декларации структуры является не совпадение. Не настоящая проблема, вы не можете маршалировать такие структуры. Рассмотрим фиксацию функции C++ и дайте ей * два * аргумента, длину и массив. И будьте осторожны, что ему нужно скопировать массив. –

+0

Как написано Гансом, и обратите внимание, что даже в C/C++ вы не пройдете по значению struct of 10mb! :-) – xanatos

+0

Можете ли вы мне помочь? и дать мне простой пример? –

ответ

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

Жалоба из-за мета атрибута для MarshallAs. Вы захотите изменить это на ByValArray.

Вместо UnmanagedType.LPArray использовать UnmanagedType.ByValArray

+0

я изменил его на '[MarshalAs (UnmanagedType.ByValArray, SizeConst = 10000000)]', но теперь у меня есть эта ошибка: Необработанное исключение типа «System.Runtime.InteropServices.MarshalDirectiveException» произошло в WindowsFormsApplication1.exe Дополнительная информация : Невозможно маршалить параметр # 1: Внутреннее ограничение: структура слишком сложная или слишком большая. –

+0

Это потому, что слишком большой массив, чтобы пройти так. Сделать размер меньше – Tim

+0

Мне нужно передать файл '.wav' ... так что он должен большой :( –