Как передать адрес метода c ++ в приложении win32 методу ac # с помощью метода параметра делегата Action - PullRequest
0 голосов
/ 26 июня 2011

У меня есть приложение win32 , использующее библиотеку C # .

В библиотеке C # есть метод, в котором делегат Action<T> является параметром, как показано ниже:

public NetSocket(Action<int, int, string> action)

У меня есть класс ref в приложении win32 с методом, соответствующим сигнатуре делегатов Action.

Как точно передать этот метод в качестве параметра Действие в методе NetSocket, указанном выше?


Бен, кажется, ваше решение работает, но произошла ошибка компиляции при сопоставлении входного параметра System:Sting ^ метода делегата действия в приложении win32 *1023* с входным параметром String делегата действия в код C # . Делегат Action в коде c # использует String в качестве входного параметра, а метод делегата Action в коде win32 пытается сопоставить, используя System::String^, чтобы сопоставить его, но это не работает.

// приложение win 32 - void ServerClass::ActionMethod(int iCommand, int iClientIndex, System::String^ message)

// win32 app -server = gcnew NetSockets::NetSocket(gcnew Action(this,&ServerClass::ActionMethod));

// csharp - public NetSocket(Action<int, int, string> action)

Есть ли какой-нибудь метод маршалинга, который мне нужно использовать, чтобы сопоставить System::String, используемый в коде win32, со строкой, используемой в коде C #? Я неправильно передаю System::String или нужно что-то еще сделать? Что я должен сделать, чтобы сопоставить параметр сообщения System::String^ со строковым параметром?
Спасибо


Исправлена ​​ошибка Я попробовал ваше решение, и оно выдало следующую ошибку:

1 ошибка C3352: 'void ServerClass::ActionMethod(int,int,System::String ^)': указанная функция не соответствует типу делегата 'void (void)'


@ Бен: Близко. Теперь, когда я компилирую код, используя ваше решение, я получаю внутреннюю ошибку компиляции, как показано:

ошибка C1001: в компиляторе произошла внутренняя ошибка.
c: \ program files (x86) \ Microsoft Visual Studio 9.0 \ vc \ include \ msclr \ marshal.h 49 1 win32project

Код скомпилирован в Visual Studio 10, где используется Framework 3.5, а не 4.0

Я проверил строку, где происходит внутренняя компиляция, и ошибка происходит здесь, в строка 49 в файле marshal.h:

_size = ::WideCharToMultiByte(CP_THREAD_ACP, WC_NO_BEST_FIT_CHARS, _pinned_ptr, _str->Length, NULL, 0, NULL,NULL);
if (_size == 0 && _str->Length != 0)
{
    throw gcnew System::ArgumentException(_EXCEPTION_WC2MB);
}

Полагаю, ошибка возникает из-за того, что входной параметр String::String^ в коде c ++ не маршалируется, вероятно, в код c # или наоборот.

Я не уверен, что мне нужно, чтобы исправить сторону кода на c ++ или сторону кода на C #. Есть идеи?

Полагаю, можно было бы просто создать dll c ++ и заставить библиотеку c # импортировать библиотеку и вызвать метод в dll c ++, а затем заставить приложение win32 загрузить dll c ++, но было бы странно иметь библиотеку загрузите dll w ++, когда dll c ++ использует библиотеку c # в качестве ссылки.


Я проверил строку, где происходит внутренняя компиляция, и здесь происходит ошибка строка 49 в файле marshal.h.

_size = ::WideCharToMultiByte(CP_THREAD_ACP, 
                              WC_NO_BEST_FIT_CHARS,
                              _pinned_ptr, 
                              _str->Length, 
                              NULL, .
                              0, 
                              NULL,
                              NULL);
if (_size == 0 && _str->Length != 0)
{
    throw gcnew System::ArgumentException(_EXCEPTION_WC2MB);
}

Полагаю, ошибка произошла из-за того, что входной параметр String :: String ^ в коде c ++ не выполняется маршалингом, вероятно, в код c # или наоборот. Не уверен, что id мне нужен для исправления isde кода c ++ или стороны кода C #.

1 Ответ

1 голос
/ 26 июня 2011

Если это встроенная функция C ++, используйте Marshal.GetDelegateForFunctionPointer

Если вы используете C ++ / CLI, как это звучит (и вам следует пометить вопрос), вам нужно что-то вроде:

NetSocket(gcnew Action<int,int,String^>(this, &ServerClass::ActionMethod))
...