none
Calling C++ dll from c# in x64 RRS feed

  • Question

  • Hi

    I have C++ dll that I need to call from C#. Interop works if both are in win32/x86. But fails in x64; C++ function parameters are garbage:

    ---- Here is C++ code ---

    #include

     

    "stdafx.h"

    #include

    "InteropTest.h"

     

    // This is an example of an exported variable

    INTEROPTEST_API

    int

    nInteropTest=0;

    // This is an example of an exported function.

    INTEROPTEST_API

    int fnInteropTest(void

    )

    {

     

    return

    42;

    }

    // This is the constructor of a class that has been exported.

    // see InteropTest.h for the class definition

    CInteropTest::CInteropTest()

    {

     

    return

    ;

    }

     

    int

     

    CInteropTest::Test(LPWSTR v1, UINT v2)

    {

     

    return

    0;

    }

      ------------ here is C# signature ------------

    [

    DllImport("InteropTest.dll", CharSet = CharSet

    .Unicode,

    EntryPoint =

    "?Test@CInteropTest@@QEAAHPEA_WI@Z"

    ,

    CallingConvention =

    CallingConvention

    .Cdecl)

    ]

     

    public static extern IntPtr

    Test(

    [

    MarshalAsAttribute(UnmanagedType

    .LPWStr)]

     

     

    string

    VMGuid,

    [

    MarshalAs(UnmanagedType

    .U4)]

    System.

    UInt32 i );

    ------

    I am calling the method as

    Test(

     

    "Some", 10);

    When viewd in debugger, the first paramaters is bad pointer in x64; end one shows different value than callter specified.

    --------

    Thanks

    jas

    

    

     

     

     
    Wednesday, October 26, 2011 6:46 PM

Answers

  • You have the C++ method declared as returning "int", but the C# signature is returning IntPtr.

     

    On x86 this is going to give you a reasonable answer, as "int" in C++ is a 4byte value, and IntPtr on x86 is 4 bytes.  However, on x64, IntPtr is 8 bytes, not 4 - so the results are going to be garbage.

     

    Try changing your C# to:

    public static extern Int32 Test(
        [MarshalAsAttribute(UnmanagedType.LPWStr)] string VMGuid,
        [MarshalAs(UnmanagedType.U4)] System.UInt32 i );
    



    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Wednesday, October 26, 2011 7:37 PM
    Moderator