简体   繁体   中英

What's wrong with this interop C#/managed/unmanaged C++ parameter passing?

I'm trying to make a non-static vendor C++ DLL accessible via C#. In order to do this, I'm writing a managed C++ wrapper DLL which basically creates static variables for the vendor DLL and makes those accessible to the C# application.

Here's an example:

typedef void(__stdcall *LPLISTENER_FUNC)(VENDORHANDLE hModule, VENDORWPARAM wParam, VENDORLPARAM lParam);

public delegate void VENDOR_Delegate(VENDORHANDLE hModule, 
  VENDORWPARAM wParam, VENDORLPARAM lParam);

public class VENDORWrapper
{
  private:
    static VENDORHSTORAGE _hStorage;
    static VENDOR_Delegate^ _hOpenCallback;

  void static Initialize()
  {
        _hStorage=storage_initialize();
  }

  void static registerCallback(unsigned int type, VENDOR_Delegate^ callback)
  {
    if (type == 2)
    {
        _hOpenCallback = callback;
        ::storage_register_callback(_hStorage, type, (LPLISTENER_FUNC)&_hOpenCallback);
    }
  }
  bool static Open(String^ file)
  {
    bool retval=false;
    filePath = file;
    IntPtr ip = Marshal::StringToHGlobalAuto(filePath);
    LPCWSTR str = static_cast<LPCWSTR>(ip.ToPointer());

            //ERROR OCCURS HERE
    retval = storage_open(_hStorage, str);

    Marshal::FreeHGlobal( ip );
    return retval;
  }

  void static Close()
  {
    storage_close(_hStorage);
  }
}

The C# is skeletal:

public static VENDORStorageWrapper.VENDOR_Delegate openCallback 
  = new VENDORStorageWrapper.VENDOR_Delegate(fileOpened);
static void Main(string[] args)
    {
        VENDORStorageWrapper.VENDORStorageWrapper.Initialize();
        Debug.WriteLine("DLL initalized");

        VENDORStorageWrapper.VENDORStorageWrapper.registerCallback(2,
            openCallback);
        Debug.WriteLine("Callback registered");

        VENDORStorageWrapper.VENDORStorageWrapper.Open("blah_file");
        Debug.WriteLine("File opened");

    }
    public static void fileOpened(System.Int32 hstorage, System.UInt32 wParam, System.Int32 lParam)
    {
        Debug.WriteLine("file opened");
    }

The vendor DLL's functions are specified as __stdcall, so I think I'm compliant on that front. The vendor's initialize call (_storage_initialize above) seems to be properly setting the handle, which is statically scoped. The storage_open call that's leading into the exception accepts a VENDORHANDLE (really a long) and an LPCWSTR, which I'm trying to convert the string passed from C# to. I think that's where the problem is...

When run, the app throws an unhandled exception "System.Runtime.InteropServices.SEHException" at the commented line above. The exception's coming from inside the vendor DLL, which I have no source code for. The vendor library works perfectly when called in an unmanaged C++ context and the file is known to be good. I think I'm missing something obvious in how I'm handling the parameters, but I can't see what it is.

I also don't think I have the callback set up properly, but I'm not the point where I can test that yet. Any ideas?

I'm not sure of the true big picture, but my experience using native DLLs with .net c# or vb, create a simple c# wrapper (just declarations) to the native DLL, instead of a c++ wrapper. Maybe this will help if the vendor DLL is really a vanilla DLL, as most are, like Windows api calls.

namespace MyNameSpace
{
   public class MyWrapper 
   {
       // passing an int to the native DLL
       [DllImport("Vendor.DLL")]
       public static extern int DllFunc1(int hModule, int nData);

       // passing a string to a native DLL expecting null terminated raw wide characters //
       [DllImport("Vendor.DLL", CharSet=CharSet.Unicode )]
       public static extern int Dllszset(int hModule, string text);
   }
}

Then .net will handle it for you and you call your vendor function as...

 MyNameSpace.MyWrapper.Dllszset(h, "hello");

Hope this helps you or someone.

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