如何将 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。
问题:
- IntPtr 是否正确?
- 如果 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);
对此有什么想法吗?似乎有效。
我在 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。
问题:
- IntPtr 是否正确?
- 如果 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);
对此有什么想法吗?似乎有效。