【发布时间】:2025-11-25 18:35:01
【问题描述】:
编辑:我已经根据@Hans Passant 的评论和@David Heffernan 的回答中的建议更新了代码。
参数c 不再为空,但x 和c 在传递回CallbackFunction 时仍然具有长度1。
我正在尝试编写将函数指针(使用委托)传递给调用函数指针的 C++ 函数的 C# 代码。
代码如下。
我遇到的问题是,当 C++ 函数 f 调用 fnPtr(x,c) 时,在 C# 函数 CallbackFunction 中,x 有一个元素(正确值为 1.0)和 c一片空白。我不知道是什么问题。
我无法更改 MyCallback 的签名。
C#代码:
using System.Runtime.InteropServices;
namespace PInvokeTest
{
class Program
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate double MyCallback(
[In] double[] x,
[Out] double[] c);
private static double CallbackFunction(
[In] double[] x,
[Out] double[] c)
{
c[0] = x[0] + x[1] + x[2];
c[1] = x[0] * x[1] * x[2];
return c[0] + c[1];
}
private static MyCallback _myCallback;
[DllImport("NativeLib", CallingConvention = CallingConvention.StdCall)]
private static extern int f(MyCallback cf);
private static void Main()
{
_myCallback = new MyCallback(CallbackFunction);
f(_myCallback);
}
}
}
NativeLib.h:
#ifndef _NATIVELIB_H_
#define _NATIVELIB_H_
#ifndef MYAPI
#define MYAPI
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef _WIN32
#ifdef MAKE_MY_DLL
#define MYAPI __declspec(dllexport) __stdcall
#else
#define MYAPI __stdcall
#endif
#else
#if __GNUC__ >= 4
#define MYAPI __attribute__ ((visibility ("default")))
#else
#define MYAPI
#endif
#endif
typedef int MyCallback(const double * x,
double * c);
MYAPI int f(MyCallback * fnPtr);
#ifdef __cplusplus
}
#endif
#endif // _NATIVELIB_H_
NativeLib.cpp:
#include "NativeLib.h"
#include <stdio.h>
#include <malloc.h>
MYAPI int f(MyCallback * fnPtr)
{
double x[] = { 1.0, 2.0, 3.0 };
double c[] = { 0.0, 0.0, 0.0 };
printf("%e\n", fnPtr(x, c));
return 0;
}
【问题讨论】:
-
委托需要 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]。从 c 参数中删除 ref,给它 [In, Out]
-
谁能评论为什么我的问题有-1票?也许这是一个愚蠢的问题(例如,解决方案很简单),但我很小心地包含了一个完整的小示例代码,并试图提出一个具体的问题。我很失望。
-
@user327301 可能是问题没有强调核心问题,一眼看不懂问题。
标签: c# pinvoke marshalling