C # вызывает родной C ++ все функции: какие типы использовать? - PullRequest
6 голосов
/ 20 марта 2011

Я хочу сделать из нативного C ++ все, что можно использовать из проекта C #.

  • Если я хочу передать строку из C # в функцию в C ++ all, какой параметр мне следует использовать?
  • Я знаю, что строки C # используют Unicode, поэтому я попробовал wchar_t* для функции, но она не работала;Я пытался перехватить все исключения, вызванные вызванной функцией, но не было выдано исключение.
  • Я также хочу вернуть строку, чтобы я мог проверить ее.

Функция C ++ являетсяследующее:

DECLDIR wchar_t * setText(wchar_t * allText) {
  return allText;
}

Код C # следующий:

[DllImport("firstDLL.Dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]     
public static extern string setText(string allText);

var allText= new string('c',4);
try {
  var str1 = setText(allText);
}
catch (Exception ex) {
  var str2 = ex.Message;
}

Какой тип я должен использовать для возвращаемого типа функции C ++, чтобы я мог вызывать его из C # с возвратомтип string[]?тот же Q, но для параметра функции будет строка [] в C #?

Ответы [ 3 ]

3 голосов
/ 20 марта 2011

Я бы, наверное, сделал это с COM BSTR и не связывался с распределением буфера. Примерно так:

C ++

#include <comutil.h>
DECLDIR BSTR * setText(wchar_t * allText)
{
    return ::SysAllocString(allText);
}

C #

[DllImport(@"firstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string setText(string allText);

BSTR - это собственный тип строки COM. Преимущество его использования в том, что память может быть выделена на собственной стороне интерфейса (в C ++) с помощью COM-распределителя, а затем уничтожена на управляемой стороне интерфейса с тем же распределителем. Маршаллер P / Invoke знает все о BSTR и обрабатывает все для вас.

Хотя вы можете решить эту проблему, передавая длину буфера, это приводит к довольно грязному коду, поэтому я предпочитаю BSTR.


Что касается вашего второго вопроса о P / Invoking string[], я думаю, вы найдете то, что вам нужно, от ответа Криса Тейлора до другого вопроса здесь, о переполнении стека.

1 голос
/ 20 марта 2011

Очень полезный сайт с инструментами и много полезной информации это http://pinvoke.net/

Это может помочь вам.

0 голосов
/ 20 марта 2011

C ++

void GetString( char* buffer, int* bufferSize ); 

C #

int bufferSize = 512; 
StringBuilder buffer = new StringBuilder( bufferSize ); 
GetString( buffer, ref bufferSize )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...