简体   繁体   中英

C# Access To Native C++ DLL

I am trying to create a program that access a native C++ DLL. Below is the sample code.

C++ Code

GetRmaPin (const char *rma_password, const char *serial, unsigned char *rma_pin);

C# Code

class Program
{
    static void Main ( string [ ] args )
    {
        string[] password = { "74f3d3a287cee548c1842c07090d6a274dd0ddbd04bfd1e4694861a369bc7304" };
        string[] serial = { "184393900006" };
        //StringBuilder rma_pin = new StringBuilder(2048);
        byte[] rma_pin = new byte[2048];

        int rc = GetRmaPin(password, serial, ref rma_pin);
        Console.WriteLine ( "Result: " + rc.ToString ( ) );
        Console.WriteLine ( "Payload: " + rma_pin.ToString ( ) );
        Console.Read ( );
    }

    [DllImport ( "Security.dll" , EntryPoint = "GetRmaPin" , CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetRmaPin (
        [In][MarshalAs ( UnmanagedType.LPArray , ArraySubType = UnmanagedType.LPStr )] string [ ] password ,
        [In][MarshalAs ( UnmanagedType.LPArray , ArraySubType = UnmanagedType.LPStr )] string [ ] serial ,
        ref byte[] rmap_in );
}

Error Message: Managed Debugging Assistant 'FatalExecutionEngineError' Message=Managed Debugging Assistant 'FatalExecutionEngineError' : 'The runtime has encountered a fatal error. The address of the error was at 0x732dc93d, on thread 0x97a4. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.'

I found a way to get the value from the 3rd argument after some experimenting. Here's the updated code. Thanks to @HansPassant for the tip to remove the "ref". Hope this is helpful to someone in the future.

class Program
{
    static void Main ( string [ ] args )
    {
        string[] password = { "74f3d3a287cee548c1842c07090d6a274dd0ddbd04bfd1e4694861a369bc7304" };
        string[] serial = { "184393900006" };
        byte[] rma_pin = new byte[32];

        int rc = GetRmaPin(password, serial, rma_pin);

        Console.WriteLine ( "Result: " + rc.ToString ( ) );
        Console.WriteLine ( "Payload: " + BitConverter.ToString ( rma_pin ).Replace ( "-" , "" ) );
        Console.Read ( );
    }

    [DllImport ( "SecurityProduction.dll" , EntryPoint = "GetRmaPin" , CallingConvention = CallingConvention.Cdecl)]
    public static extern int GetRmaPin (
        [In][MarshalAs ( UnmanagedType.LPArray , ArraySubType = UnmanagedType.LPStr )] string [ ] password ,
        [In][MarshalAs ( UnmanagedType.LPArray , ArraySubType = UnmanagedType.LPStr )] string [ ] serial ,
        byte[] rmap_in );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM