admin管理员组

文章数量:1196136

I'm trying to export a function so that it can be used from the native unmanaged world. In my case this would be a Delphi application.

I'm using [UnmanagedCallersOnly] keyword to export the functions. And I use DNNE () to generate the appropriate wrapper file.

Returning a string from a function is as simple as

[UnmanagedCallersOnly]
public static IntPtr Foo()
{
  return Marshal.StringToBSTR("hello from c#");
}

But I also need to return "complex" structures. So I created a struct

    public struct ReturnTest
    {
        public int code;
        public IntPtr txt;
    }

and use this in my function

    [UnmanagedCallersOnly]
    public static ReturnTest TestFunction()
    {
        ReturnTest returnTest = new ReturnTest();
        returnTest.code = 1337;
        returnTest.txt = Marshal.StringToBSTR("a b c d q ¥ K xyz");
        return returnTest;
    }

But during the compiling it errors out:

The command ""C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\cl.exe" /Od /LDd /TC /MT /GS /Zi /D DNNE_ASSEMBLY_NAME=UnmanagedCallersOnlyStructReturn /D DNNE_COMPILE_AS_SOURCE /I "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\include" /I "C:\Users\XXXX\.nuget\packages\dnne\2.0.7\tools\platform" /I "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\9.0.1\runtimes\win-x64\native" /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\shared" /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um" /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt"  "C:\git\stackoverflow\UnmanagedCallersOnlyStructReturn\obj\Debug\net8.0-windows7.0\dnne\UnmanagedCallersOnlyStructReturn.g.c" "C:\Users\XXXX\.nuget\packages\dnne\2.0.7\tools\platform\platform.c" /link /DLL /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\lib\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x64" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\9.0.1\runtimes\win-x64\native\libnethost.lib" Advapi32.lib /IGNORE:4099 /IMPLIB:"C:\git\stackoverflow\UnmanagedCallersOnlyStructReturn\obj\Debug\net8.0-windows7.0\dnne\bin\UnmanagedCallersOnlyStructReturnNE.lib" /OUT:"C:\git\stackoverflow\UnmanagedCallersOnlyStructReturn\obj\Debug\net8.0-windows7.0\dnne\bin\UnmanagedCallersOnlyStructReturnNE.dll" " exited with code 2.

syntax error: '__cdecl'

What are I'm doing wrong?

Full source code available here:

I'm trying to export a function so that it can be used from the native unmanaged world. In my case this would be a Delphi application.

I'm using [UnmanagedCallersOnly] keyword to export the functions. And I use DNNE (https://github.com/AaronRobinsonMSFT/DNNE) to generate the appropriate wrapper file.

Returning a string from a function is as simple as

[UnmanagedCallersOnly]
public static IntPtr Foo()
{
  return Marshal.StringToBSTR("hello from c#");
}

But I also need to return "complex" structures. So I created a struct

    public struct ReturnTest
    {
        public int code;
        public IntPtr txt;
    }

and use this in my function

    [UnmanagedCallersOnly]
    public static ReturnTest TestFunction()
    {
        ReturnTest returnTest = new ReturnTest();
        returnTest.code = 1337;
        returnTest.txt = Marshal.StringToBSTR("a b c d q ¥ K xyz");
        return returnTest;
    }

But during the compiling it errors out:

The command ""C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\bin\Hostx64\x64\cl.exe" /Od /LDd /TC /MT /GS /Zi /D DNNE_ASSEMBLY_NAME=UnmanagedCallersOnlyStructReturn /D DNNE_COMPILE_AS_SOURCE /I "C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\include" /I "C:\Users\XXXX\.nuget\packages\dnne\2.0.7\tools\platform" /I "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\9.0.1\runtimes\win-x64\native" /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\shared" /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um" /I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt"  "C:\git\stackoverflow\UnmanagedCallersOnlyStructReturn\obj\Debug\net8.0-windows7.0\dnne\UnmanagedCallersOnlyStructReturn.g.c" "C:\Users\XXXX\.nuget\packages\dnne\2.0.7\tools\platform\platform.c" /link /DLL /LIBPATH:"C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.42.34433\lib\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x64" "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64\9.0.1\runtimes\win-x64\native\libnethost.lib" Advapi32.lib /IGNORE:4099 /IMPLIB:"C:\git\stackoverflow\UnmanagedCallersOnlyStructReturn\obj\Debug\net8.0-windows7.0\dnne\bin\UnmanagedCallersOnlyStructReturnNE.lib" /OUT:"C:\git\stackoverflow\UnmanagedCallersOnlyStructReturn\obj\Debug\net8.0-windows7.0\dnne\bin\UnmanagedCallersOnlyStructReturnNE.dll" " exited with code 2.

syntax error: '__cdecl'

What are I'm doing wrong?

Full source code available here: https://github.com/JYPDWhite/UnmanagedCallersOnlyStructReturn

Share Improve this question edited Jan 23 at 15:07 White asked Jan 23 at 12:53 WhiteWhite 3471 silver badge10 bronze badges 4
  • Try removing [UnmanagedCallersOnly] – jdweng Commented Jan 23 at 13:22
  • I need [UnmanagedCallersOnly] this function shall be called from the native world. – White Commented Jan 23 at 13:34
  • It is meant when a function is called from c++ managed code. You are calling from managed c# code. – jdweng Commented Jan 23 at 16:47
  • Have you considered using the DllExport library github.com/3F/DllExport – Charlieface Commented Jan 24 at 0:28
Add a comment  | 

1 Answer 1

Reset to default 2

According to this issue, it seems that this library does not know how to translate the C# struct. You need to manually declare the C struct as follow:

[UnmanagedCallersOnly]
[DNNE.C99DeclCode("struct ReturnTest{int code; intptr_t txt;};")]
[return: DNNE.C99Type("struct ReturnTest")]
public static ReturnTest TestFunction()
{
    ReturnTest returnTest = new ReturnTest();
    returnTest.code = 1337;
    returnTest.txt = Marshal.StringToBSTR("a b c d q ¥ K xyz");
    return returnTest;
}

本文标签: cUnmanagedCallersOnly and struct as return valueStack Overflow