2016-05-17 6 views
1

Можно ли сделать что-то вроде этого:Как передать параметр, который может иметь тип int/double/string/int [] из C# в native C?

Native DLL:

void SetFieldValue(const char *Field, void *pValue, int Count) 
{ 
    char *StrValue; 
    int *IntArrayValue; 
    if (!strcmp(Field, "StrField")) 
    { 
     StrValue = malloc((Count + 1) * sizeof(char)); 
     strcpy(StrValue, (char *)pValue); 
     DoSomethingWithStringValue(StrValue); 
     free(StrValue); 
    } 
    else if (!strcmp(Field, "IntArrayField")) 
    { 
     IntArrayValue = malloc(Count * sizeof(int)); 
     memcpy(IntArrayValue, pValue, Count); 
     DoSomethingWithIntArrayValue(IntArrayValue); 
     free(StrValue); 
    } 
    //... and so on 
} 

Управляется:

[DllImport(DllName, CallingConvention = DllCallingConvention)] 
private static extern void SetFieldValue(string fieldName, IntPtr value, int count); 


public void SetIntArray() 
{ 
    int[] intArray = { 1, 2, 3 }; 
    SetFieldValue("IntArrayField", intArray, 3); 
} 


public void SetString() 
{ 
    SetFieldValue("StrField", "SomeValue", 9); 
} 

//... and so on 
+0

В чем проблема? Ваш код выглядит нормально для меня. – LPs

+0

Моя проблема в том, что PInvoke печально известен тем, что трудно найти ошибки. Я пытаюсь понять, как эти вещи лучше всего/наиболее безопасно. –

ответ

3

Один из способов заключается в использовании метода перегрузки. На стороне C# вы должны объявить несколько версий импортированной функции. Для двух примеров в вопросе, который будет выглядеть следующим образом:

[DllImport(DllName, CallingConvention = DllCallingConvention)] 
private static extern void SetFieldValue(string fieldName, int[] value, int count); 

[DllImport(DllName, CallingConvention = DllCallingConvention)] 
private static extern void SetFieldValue(string fieldName, string value, int count); 

Эти два р/вызова функции связаны с одной и той же одной неуправляемой функции. Для первой перегрузки аргумент value сортируется как указатель на первый элемент массива. Для второй перегрузки аргумент value сортируется как указатель на массив символов с нулевым символом. В обоих случаях это то, что вам нужно.

+0

спасибо! об этом я никогда не слышал. поэтому, когда вы делаете так, родной код, как и в моем вопросе? это действительно похоже на опрятный способ сделать это. –

+0

Лучше всего включить перегрузку, которая использует тип значения, слишком легко забыть использовать 'ref'. –

+0

@HansPassant: Спасибо, но я не понял: «Лучше всего включить перегрузку, которая использует тип значения, слишком легко забыть использовать ref». Я понял вашу перегрузку на управляемой стороне, но я спрашивал, есть ли мой собственный C-код. C - не имеет перегрузки. –