2014-07-31 4 views
1

У меня есть проект C++, содержащий метод неуправляемой класс, используемый для отображения строки в пользовательском интерфейсе:Передача родной функции указатель на метод C#

void MyProject::displayIHM(std::string mystring); 

Этот проект компилируется с/CLR, потому что он вызывает еще один сделанный с помощью C# /. NET 4.0. Цель проекта .NET - сделать тяжелые задачи вычисления. Во время вычисления мы хотим получить от него некоторую информацию в пользовательском интерфейсе.

Моя идея состояла в том, чтобы создать два новых метода в C++ - кли проект:

void MyProject::displayFromDotNet(String^ mystring) 
{ 
     displayIHM(ToStdString(mystring)); 
} 

string ToStdString (String^s) 
{ 
    const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer(); 
    string os = chars; 
    Marshal::FreeHGlobal(IntPtr((void*)chars)); 
    return os; 
} 

До сих пор все в порядке, но теперь трудная часть: как обеспечить displayFromDotNet для проекта .NET. Моя идея состояла в том, чтобы обеспечить указатель на функцию в конструктор класса .NET, а затем запустить процесс:

void (MyProject::*pointeurFunc)(String^) = &MyProject::displayFromDotNet; 
ComputationProject^ kernel = gcnew ComputationProject((this->*pointeurFunc)); 
kernel->Compute(); 

Вторая линия не работает. У конструктора ComputationProject есть параметр IntPtr, но я не знаю, могу ли я преобразовать указатель на IntPtr^в C++. Я также сделал несколько попыток с использованием Marshal :: GetDelegateForFunctionPointer, но он не смог скомпилировать.

Я не знаю, что делать, любая помощь будет оценена!

EDIT: yes ComputationProject - мой проект C# /. NET. Ошибка с строкой 2 «не может преобразовать параметр 1 из« перегруженного типа функции »в« System :: IntPtr ».

+0

Описание проблемы может быть понятнее. Я предполагаю, что ComputationProject является классом C#? Когда вы говорите: «Вторая строка не работает», вы имеете в виду, что она генерирует ошибку компиляции или ошибку времени выполнения. Я бы ожидал, что указатель на функции C/C++ будет больше делегатом на C#. Взгляните на http://stackoverflow.com/questions/11425202/is-it-possible-to-call-ac-function-from-c-net и http://stackoverflow.com/questions/6077329/how- do-i-call-ac-function-from-c-sharp и посмотреть, поможет ли это – Dweeberly

+0

Я редактирую свой вопрос. К сожалению, ваши ссылки мне не помогают. Я не могу использовать импорт DLL в моем проекте .NET (ComputationProject), так как мне нужно получить метод класса (а не статический метод). Я должен кормить его с помощью конструктора и gcnew, но я не знаю, как это сделать. – NicoGDF

+0

Вам нужно будет обернуть функцию экземпляра C++ в управляемом делетете –

ответ

-1

Я наконец нашел (уродливый) способ.

Моя основная проблема заключалась в том, что я не мог передать указатель метода на C#, поскольку он не является реальным указателем на функцию (поэтому я не могу передать его в IntPtr). я решил создать второй класс, содержащий статический объект MyProject и статический метод, призывающую displayIHM на статический объект:

class StaticMyProject 
{ 
public : 
    static MyProject staticObject; 
    static void DisplayInIHM(char *); 
}; 

В CPP:

MyProject StaticMyProject::objetStatique; 

void StaticMyProject::DisplayInIHM(char *message) 
{ 
    std::string message2(message); 
    staticObject.displayIHM(message2); 
} 

Теперь для вызова метода Compute из ComputationProject, я модифицировал код так:

StaticMyProject::objetStatique = *this; 
void (*funcPointer)(char*) = StaticMyProject::DisplayInIHM; 
ComputationProject^ kernel = gcnew ComputationProject((IntPtr)funcPointer); 
kernel->Compute(); 

И в моем ComputationProject.cs:

public class ComputationProject 
    { 
     [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
     public delegate void FunctionPointer([MarshalAs(UnmanagedType.LPStr)]string message); 

     public readonly FunctionPointer DisplayMethod; 

     public ComputationProject(IntPtr ptr) 
     { 
      this.DisplayMethod = (FunctionPointer)Marshal.GetDelegateForFunctionPointer(ptr, typeof(FunctionPointer));      
     } 

     public int Compute() 
     {    
      this.DisplayMethod("Beginning computation..."); 
      ... 
     } 
    } 
+0

-1 Это действительно ужасно. Используйте делегат. –

+0

Вам нужен управляемый класс для реализации делегата. Он делает это, вызывая неуправляемую функцию экземпляра. –

+0

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

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