P / Invoke返回无效*

时间:2014-01-03 14:45:09

标签: c# c pinvoke

我有一个带有以下签名的C函数:

int __declspec(dllexport) __cdecl test(void* p);

功能实现如下:

int i = 9;

int test(void* p)
{
    p = &i;
    return 0;
}

从C#应用程序,我想通过指向C#应用程序的指针返回引用的值,所以我做了以下内容:

[DllImport(@"lib\test.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int test(out IntPtr p);

IntPtr p = IntPtr.Zero;

test(out p);

但是,p没有任何价值。

请帮助!!

3 个答案:

答案 0 :(得分:3)

如果要更改调用者指针参数的值,则需要将指针传递给指针:

int test(void** p)
{
    *p = &i;
    return 0;
}

从C#调用类似

的东西
[DllImport(@"lib\test.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern unsafe int test(IntPtr* p);

public unsafe void DotNetFunc()
{
    IntPtr p;
    test(&p);

如果您不喜欢使用unsafe,则可以更改C函数以返回指针,如有必要,返回NULL以指示错误。

int* test()
{
    return &i;
}

[DllImport(@"lib\test.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr test();

IntPtr p = test();
if (p == IntPtr.Zero)
    // error

答案 1 :(得分:3)

您不需要不安全的代码。但是你确实需要修复C代码。像这样:

void test(int** p)
{
    *p = &i;
}

C#代码是:

[DllImport("...", , CallingConvention=CallingConvention.Cdecl)]
static extern void test(out IntPtr p);

这样称呼:

IntPtr p;
test(out p);

并读取这样的值:

int i = Marshal.ReadInt32(p);

或者将指针返回为函数返回值:

int* test(void)
{
    return &i;
}

在C#中:

[DllImport("...", , CallingConvention=CallingConvention.Cdecl)]
static extern IntPtr test();

我相信你可以做其余的事。

答案 2 :(得分:0)

尝试使用指针指针

int test(void** p)
{
    *p = &i;
    return 0;
}