简体   繁体   English

将本机指针函数传递给C#方法

[英]Passing a native pointer function to a C# method

I have a C++ project containing a nonmanaged class method used to display string in a user interface : 我有一个C ++项目,其中包含用于在用户界面中显示字符串的非托管类方法:

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

This project is compiled with /clr because it calls another one made with C#/.NET 4.0. 该项目用/ clr编译,因为它调用了另一个用C#/。NET 4.0创建的项目。 The goal of the .NET project is to make heavy computation tasks. .NET项目的目标是进行繁重的计算任务。 During computation, we want to get back from it some information to the user interface. 在计算过程中,我们希望从中获得一些信息返回到用户界面。

My idea was to create two new methods in the C++-cli project : 我的想法是在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;
}

Until now, everything is ok but now the difficult part : how to provide displayFromDotNet to the .NET project. 到现在为止,一切都还可以,但现在困难的部分:如何将displayFromDotNet提供给.NET项目。 My idea was to provide a function pointer in the constructor of the .NET class and then to launch the process : 我的想法是在.NET类的构造函数中提供一个函数指针,然后启动该过程:

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

The second line does not work. 第二行不起作用。 The constructor of ComputationProject has a IntPtr parameter but I do not know if I can convert a function pointer to an IntPtr^ in C++. ComputationProject的构造函数具有IntPtr参数,但是我不知道是否可以在C ++中将函数指针转换为IntPtr ^。 I also made some attempts using Marshal::GetDelegateForFunctionPointer but it could not compile. 我也尝试使用Marshal :: GetDelegateForFunctionPointer,但无法编译。

I do not know what to do, any help would be appreciated! 我不知道该怎么办,任何帮助将不胜感激!

EDIT : yes ComputationProject is my C#/.NET project. 编辑:是的ComputationProject是我的C#/。NET项目。 The error with line 2 is "cannot convert parameter 1 from 'overloaded function type' to 'System::IntPtr'". 第2行的错误是“无法将参数1从“重载函数类型”转换为“ System :: IntPtr””。

I finally find a (ugly) way. 我终于找到了(丑陋的)方法。

My main problem was I could not pass a method pointer to C# because it is not a real function pointer (so I cannot cast it to IntPtr). 我的主要问题是我无法将方法指针传递给C#,因为它不是真正的函数指针(因此我无法将其强制转换为IntPtr)。 I decided to create a second class containing a static MyProject object and a static method calling displayIHM on the static object : 我决定创建第二个类,其中包含一个静态MyProject对象和一个在静态对象上调用displayIHM的静态方法:

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

In cpp : 在cpp中:

MyProject StaticMyProject::objetStatique;

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

Now for calling Compute method of ComputationProject, I modified the code like this : 现在,为了调用ComputationProject的Compute方法,我修改了如下代码:

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

And in my ComputationProject.cs : 在我的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...");
            ...
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM