如何使用WCHAR*out参数从C#调用C函数?

but*_*ach 5 c c# interop marshalling

我在编组方面遇到了一些问题,而我自己也无法解决这个问题.我已经搜索了这个主题,但还没有运气,所以基本上我试图从我的托管C#应用程序调用非托管C函数.C函数的签名如下所示:

long MyFunction(WCHAR* upn, long upnSize, WCHAR* guid, long* guidSize);
Run Code Online (Sandbox Code Playgroud)

我没有访问.dll文件,我只知道该函数正在暴露使用,我知道该函数应该做什么,但我不知道里面发生了什么,所以函数收到一个WCHAR*upn持有UserPricipalName和长度与提供的UPN的长度.还传递WCHAR指针,其中该函数写回与传递的UPN相关联的相应GUID.guidSize指针提供指针的大小,如果它太小,则写入的GUID未完全写入.如果一切顺利,函数应该返回0(当从c#调用时,它从未发生过)

现在,我调用和调用此函数的努力如下所示:

[DllImport(@"MyDll.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
public static extern long MyFunction(IntPtr upnPtr, long upnSize, [Out, MarshalAsAttribute(UnmanagedType.LPWStr) ] StringBuilder guidPtr, IntPtr guidSizePtr);


//my attempt to call the Dll's exposed function
string upn = foo@bar.com;
long upnSize = upn.Length;
IntPtr upnPtr = Marshal.StringToHGlobalUni(upn);

IntPtr guidSizePtr = Marshal.AllocHGlobal(sizeof(long));
Marshal.WriteInt32(GuidSizePtr, 128);
var guidSB = new StringBuilder(128);

result = MyFunction(upnPtr, upnSize, guidSB, guidSizePtr);
Run Code Online (Sandbox Code Playgroud)

结果我收到一个AccessViolationException.我玩了很多变种来调用函数,但我从来没有设法收到0作为返回值,我从来没有能够读出GUID,因为我应该这样做.

任何帮助都将不胜感激.

log*_*cnp 8

将函数声明为:

    [DllImport(@"MyDll.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
    public static extern int MyFunction([MarshalAsAttribute(UnmanagedType.LPWStr)] string upnPtr, int upnSize, [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder guidPtr, ref int guidSizePtr);
Run Code Online (Sandbox Code Playgroud)

称其如下:

        string upn = "foo@bar.com";
        var guidSB = new StringBuilder(128);
        int guidSizePtr =guidSB.Capacity;
        MyFunction(upn, upn.Length, guidSB, ref guidSizePtr);
Run Code Online (Sandbox Code Playgroud)

请注意,C++中的长度为32位,因此您应该在C#代码中将所有此类实例定义为int.