2009-03-23 1 views
8

Все примеры, которые я могу найти, используя DLLImport для вызова кода C++ из C#, передают ints взад и вперед. Я могу заставить эти примеры работать нормально. Метод, который мне нужен, требует двух структур в качестве параметров импорта, и я не совсем понимаю, как я могу это сделать.Как использовать DLLImport с structs как параметры в C#?

Вот что я должен работать с:

у меня есть код C++, так что я могу делать какие-либо изменения/дополнения к нему, что мне нужно.

Приложение третьей стороны загрузит мою DLL при запуске и ожидает, что DLLExport будет определен определенным образом, поэтому я не могу реально изменить подписи метода, который будет экспортироваться.

Приложение C#, которое я создаю, будет использоваться в качестве обертки, поэтому я могу интегрировать эту часть C++ в некоторые из наших других приложений, которые все написаны на C#.

++ сигнатура метода C Мне нужно позвонить выглядит так

DllExport int Calculate (const MathInputStuctType *input, 
    MathOutputStructType *output, void **formulaStorage) 

И MathInputStructType определяется как следующий

typedef struct MathInputStuctTypeS { 
    int    _setData; 
    double    _data[(int) FieldSize]; 
    int    _setTdData; 
} MathInputStuctType; 

ответ

9

В статье MSDN Passing Structures есть хорошее представление о передаче структур неуправляемому коду. Вы также захотите посмотреть на Marshaling Data with Platform Invoke и Marshaling Arrays of Types.

+0

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

4

Из декларации вы публикуемую, ваш C# код будет выглядеть примерно так :

[DllImport("mydll.dll")] 
static extern int Calculate(ref MathInputStructType input, 
    ref MathOutputStructType output, ref IntPtr formulaStorage); 

В зависимости от структуры MathInputStructTyp e и MathOutputStructType в C++, вам также придется атрибутировать эти объявления структуры, чтобы они правильно маршалировали.

+0

Отсутствует имя функции btw :) – leppie

+0

«вам также придется атрибутировать эти объявления структуры, чтобы они правильно маршалировали». Правильно, это та часть, которую я действительно не понимаю. Я добавил структуру к моему вопросу. –

3

Для структуры:

struct MathInputStuctType 
{ 
    int  _setData; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = FieldSize)] 
    double[] _data; 
    int  _setTdData; 
} 
+0

Я не уверен, что это на 100% необходимо, но вы должны установить ArraySubType для UnmanagedType.R8 для поля _data. – JaredPar

+0

Это должно быть выведено (я полагаю, поскольку маршаллер довольно хорош). – leppie

2

Вы можете посмотреть на этот проект на CodePlex, http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120. Это должно помочь вам правильно упорядочить структуры.

+0

Это выглядит классно и все, но независимо от того, какую DLL я выбираю, он продолжает говорить мне, что ожидает манифест. Похоже, классный инструмент, если он работает. –

+0

Не знал, что это было ограничительным, извините. – LanceSc

+0

Не беспокойтесь, спасибо за помощь. –

Смежные вопросы