2013-07-10 2 views
2

Я пишу программу для отдела химии моего колледжа, включающую три отдельных устройства - датчик силы, стадию наноосаждения на оси Z и ось пикомотора оси XYZ. Я должен включить эти три устройства в одну программу и связать их друг с другом. Я уже успешно включил датчик силы и ось Z-оси. Они оба пришли с DLL, готовыми для C#. Поскольку я пишу программу GUI, и я уже довольно хорошо знаком с C#, это был естественный выбор.Использование библиотеки DLL, написанной в/для C++ в программе C#

Однако DLL сцены XYZ была написана для C++. Я не уверен, как заставить эту DLL работать в моей программе. Я не могу добавить ссылку на него в Visual Studio, потому что он несовместим, а файлы заголовков, которые поставляются с ним, которые раскрывают функции в DLL, были написаны для C++.

У меня есть базовое понимание процесса. В заголовке ldcncom.h, there'es функции записывается в виде так:

DLLENTRY(int) LdcnInit(char *portname, unsigned int baudrate); 

я переписал его, как это в моей C# программы:

[DllImport("Ldcnlib.dll", EntryPoint = "LdcnInit")] 
public static extern int LdcnInit(char[] portname, uint baudrate); 

я не уверен, если это правильно, но он «работал», поскольку он мог читать функцию из DLL и выполнять ее долг ... просто не совсем правильно, потому что он все еще не выполняет всех других функций.

Но я не уверен, как сделать все остальное. Например, в sio_util.h существует функция с возвращаемым типом HANDLE, другая с типом возвращаемого значения DWORD, и я не очень хорошо знаком с ними и не знаю, как заставить его работать на C#.

Я слышал о таких вещах, как interop, wrappers, C++/CLI, но в данный момент это немного вне меня (все еще несколько нового для всего этого), поэтому любые советы о том, как сделать этот процесс, будут отличными ,

спасибо.

ответ

4

But I'm not sure how to do the rest. For instance, in sio_util.h, there's a function with a return type of HANDLE, another with a return type of DWORD, and I'm not very familiar with these and don't know how to make it work in C#.

DWORD является 32-битовым беззнаковым целым числом, так что вы будете использовать UInt32 (uint), чтобы представить это.

HANDLE является void*, или любой указатель, поэтому вы обычно используют IntPtr представлять HANDLE в C#.

На странице Windows Data Types перечислены большинство стандартных типов Windows, что должно стать хорошей отправной точкой при определении типов P/Invoke, которые вам нужны.

+0

Отличная ссылка. Спасибо @ReedCopsey – crush

+0

Благодарим за ответ. Поэтому я мог бы по существу повторить процесс, который я сделал для этой одной функции (ldcninit), переписывая ее как DllImport и т. Д. Для каждой другой функции и достигнуть хорошего места? –

+0

@RobertJosephDacunto Да - это идея - вы просто создаете декларацию '[DllImport]' для соответствия каждому методу. Я бы, лично, завернул это в класс C#, когда закончите, поэтому использование «чистое». –

1

Если вам нужно преобразовать больше типов данных C++ в C# и найти его много времени, есть отличный инструмент «P/Invoke Signature Generator», который упрощает эту работу. Here - хорошая статья о том, как его использовать.

Вы должны скопировать основную подпись метода, и инструмент генерирует подпись C#.

+0

Спасибо за ссылку. Программа кажется очень полезной. Я загрузил его и перешел на третью вкладку (SigImp Translate Snippet), которая, похоже, для моего собственного кода. Я набрал одну из функций и щелкнул сгенерировать, но я получаю сообщение об ошибке «Ошибка: ожидаемый токен типа ParenClose, но вместо него найден IntKeyword». Возможно, я использую это неправильно. –

+0

Что такое встроенная подпись метода? можете ли вы поделиться им? –

+0

Я, вероятно, неправильно использую программу, но в открытом файле (ldcncom.h) есть куча функций, которые я хочу «преобразовать». Это один из них: 'DLLENTRY (int) LdcnInit (char * portname, unsigned int baudrate);' –

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