将托管事件处理程序传递给Linux中的非托管代码

时间:2017-05-23 22:24:05

标签: c# c++

我一直在为将在Linux下运行的现有C ++库编写.Net Core C#包装器。该库具有以下内容:

int newrelic_record_metric(const char *name, double value);

void newrelic_register_message_handler(void*(*handler)(void*));

void *newrelic_message_handler(void *raw_message);

第一种方法很容易包装:

internal static class AgentSdkWrapper {
    [DllImport("newrelic-transaction")]
    public static extern unsafe int newrelic_record_metric(StringBuilder name, double value);

我正在努力使用第二个版本的签名,我不知道如何将其转换为C#。我知道我正在处理无效指针,但我不确定如何处理它们。

另外,根据库文档,我需要将第三种方法注册为第二种方法的回调:

  

您必须注册所需的回调,以便在完成交易时将数据发送到New Relic。您需要注册已定义的默认newrelic_message_handler回调:

     

newrelic_register_message_handler(newrelic_message_handler);

我认为我需要将newrelic_message_handler分配给C#委托并将其传递给newrelic_register_message_handler,但我不清楚我是如何到达那里的。

1 个答案:

答案 0 :(得分:-1)

如果我正确理解了doc,你只需要将指向newrelic_message_handler的指针传递给第二个函数。

这意味着,对于所有意图和目的,您的第二个功能将如下所示:

[DllImport(...)]
static extern void newrelic_register_message_handler(IntPtr handler);

因为实际上你只是传递一个指针并且并不真正关心类型。

要获取指向newrelic_message_handler的指针(假设这是一个dll导出函数),您需要使用GetProcAdress

[DllImport("kernel32", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibrary(string lpFileName);

您的最终代码将是:

var module = LoadLibrary("newrelic-transaction");
var proc = GetProcAddress(module, "newrelic_message_handler");
newrelic_register_message_handler(proc);