我有一个C ++项目,其中包含一个非托管类方法,用于在用户界面中显示字符串:
void MyProject::displayIHM(std::string mystring);
这个项目是用/ clr编译的,因为它调用另一个用C#/ .NET 4.0编写的项目。 .NET项目的目标是进行繁重的计算任务。在计算过程中,我们希望从中获取一些信息到用户界面。
我的想法是在C ++中创建两个新方法 - cli项目:
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参数,但我不知道我是否可以在C ++中将函数指针转换为IntPtr ^。我也尝试使用Marshal :: GetDelegateForFunctionPointer,但无法编译。
我不知道该怎么做,任何帮助都会受到赞赏!
编辑:是的ComputationProject是我的C#/ .NET项目。第2行的错误是“无法将参数1从'重载函数类型'转换为'System :: IntPtr'”。
答案 0 :(得分:-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);
}
现在,为了调用ComputationProject的Compute方法,我修改了这样的代码:
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...");
...
}
}