how to call a C function from C# with a WCHAR* out parameter?

我的未来我决定 提交于 2020-01-13 02:23:08

问题


I'm having a bit of problem with marshaling and I just can't figure it out by myself. I've searched for this topic, but hadn't have any luck yet, so basically I'm trying to call an unmanaged C function from my managed C# application. The signature of the C function looks like this:

long MyFunction(WCHAR* upn, long upnSize, WCHAR* guid, long* guidSize);

I don't access to the .dll file, I just know that the function is being exposed for usage and I know what the function is supposed to do, but I don't know what happening inside, so the function receives a WCHAR* upn holding a UserPricipalName and a long with the length of the supplied UPN. Also a WCHAR pointer is passed along, where the function writes back a corresponding GUID which is associated with the passed UPN. The guidSize pointer supplies the size of the pointer, if it's too small the written GUID is not fully written. If everything goes fine the function should return 0 (it never happened yet, when called from c#)

Now my efforts to invoke and call this function look like this:

[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);

as a result I receive an AccessViolationException. I've played around with many variations to call the function, but I never managed to receive a 0 as return value and I was never able to read out the GUID as I'm supposed to do.

Any help with this would be appreciated.


回答1:


Declare the function as:

    [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);

Call it as follows:

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

Note that long in C++ is 32-bit, so you should define all such instances as int in your C# code.



来源:https://stackoverflow.com/questions/11879108/how-to-call-a-c-function-from-c-sharp-with-a-wchar-out-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!