如何将 void *(指向 double 或 int)从 C 传递到 C#

how to pass void * (pointing to double or int) from C to C#

我在 C:

中有通用回调类型
typedef int(*OverrideFieldValueSetCB_t)(const char *Dialog, const char *FieldName, void *Value);

和回调:

OverrideFieldValueSetCB_t       gOverrideFieldValueSetCB;

我在 C 代码中调用的函数将值传递给 C# :

int DllGuiSetFieldValue(const char *Dialog, const char *FieldName, void *pValue)
{   
    return gOverrideFieldValueSetCB(Dialog, FieldName, pValue);
}

在 C# 代码中我设置了这种委托:

private static int OverrideFieldValueSetCb(string dialogName, string fieldName, IntPtr value)
{
    ///...
}

在上面,我想 marshal/cast 值根据 fieldName 为 int 或 double。

问题:

  1. IntPtr 是否正确?
  2. 如果 IntPtr 是正确的,如何 cast/marshal 将其转换为 double 或 int ?

"Pointing to double or int"自找麻烦

但如果您确定这是您想要的方式,请查看 Marshal class - Marshal.ReadInt32 for int,以及 Marshal.PtrToStructure<double> 对于 double。确保不要把两者搞混:)

当然,如果能用unsafe代码,就不用Marshal了。就像在 C 中一样进行转换。

示例:

double val = 123.45d;
double second;
double third;

unsafe
{
  void* ptr = &val;

  second = *(double*)ptr;
  third = Marshal.PtrToStructure<double>(new IntPtr(&val));
}

second.Dump();

如果 dialogName 和 fieldName 表示它是双重的,我会这样做:

    private int ChangeFieldValue(string fieldName, IntPtr newValue)
    {
        double[] destination = new double[1];
        Marshal.Copy(newValue, destination, 0, 1);

对此有什么想法吗?似乎有效。