locked
How do you create a WPF app that accesses a 32-bit unmanaged c++ DLL? RRS feed

  • Question

  • I have an SDK for a USB-connected camera. This is a 32-bit, unmanaged, c or c++ dll, with no source code. It comes with an import library (.lib file), several c/c++ header files, and virtually no documentation.
    I am writing a WPF application that I want to use to call the API methods in the SDK. As I understand it, I need to write a C++/CLI 'wrapper' class library to make the methods in the SDK DLL accessible to the C# application.
    I have been working on this for several days, and have read literally hundreds of articles/texts/etc. on StackOverflow, Microsoft documentation pages, and dozens of other sources. I just keep running into one problem after another, and all the resources I've found seem to be missing some critical piece of the puzzle.
    I apologize for the way I am presenting this, but here are some of the questions I have:

     1. Do I need to "Copy Always" or "Copy if Newer" the API dll to the $Solution folder?
     2. Do I need a Reference in the Wrapper project to reference the API dll?
     3. In the wrapper, do I need to specify an 'extern' declaration to API methods?
     4. In the wrapper, do I need to specify an 'extern "C"' declaration to API methods?
     5. Do I use PInvoke to call API methods?
     6. Do I use the DllImportAttribute to tell where to find the API method?
     7. Do I need to specify the Calling Convention for the API method?
     8. Do I need to use LoadLibrary to get access to the API dll?
     9. Do I need to link to a static .lib (import library) file from my Wrapper project?
    10. Does the Project Platform of my Wrapper need to be x86 (for a 32-bit API dll)?
    11. Can the Project Platform for the C# .NET app be "Any CPU"?
    12. Will the JIT compiler figure out at runtime what platform to compile to?
    13. Is 'Marshaling' required between the C# app and the managed c++/CLI Wrapper?
    14. Is 'Marshaling' required between the managed c++/CLI Wrapper and the unmanaged API dll?
    15. Is COM required for a c# app to use an unmanaged c/c++ .dll library?
    16. Do I need to use System.Runtime.InteropServices?
    17. Do I need to set "prefer 32-bit" on the solution or either of the projects?

    Thank you!

    Friday, May 15, 2020 5:20 PM

Answers

  •  1 copy if newer unless you sometimes change your machine time into the future.

    2 nope. the C++ way to reference a dll is to include headers then link to a lib 

    3 nope. the header files from the SDK should already done that. 

    4 nope see 3. 

    5 you include the header files that comes with the dll. the linker should resolve calls to APIs to dll entry points based on the lib that comes with the dll.

    6 no, the way you use it is through implicit pinvoke, see 5

    7 yes it needs to be the same between caller and callee. Since source code of the dll is not available you have to guess. it is most likely the default on both ends though. 

    8 nope, you got the lib file already, no need of LoadLibrary.

    9 yes, see 8

    10 yes, your wrapper must target the same architecture or it cannot load the API DLL. 

    11 nope. since the source code is not available and only a 32 bit of the SDK is available, your wrapper cannot support 64 bit.

    12 nope, see 11. 

    13  no, you won't exposing a C++ interface in your wrapper DLL. the whole point of wrapper is to expose a CLS compliant interface that can be used by .Net languages. 

    14 yes it is your job to marshal data (that is, copy data between the native heap and the managed heap) in the wrapper dll. see https://docs.microsoft.com/en-us/cpp/dotnet/how-to-wrap-native-class-for-use-by-csharp?view=vs-2019

    15 only if the native component only has a COM interface. in your case your DLL doesn't have one.

    16 I don't see how you get around the Marshal class in there since the job of your wrapper DLL is marshalling.

    17 nope, x86 only. see 11. 



    Visual C++ MVP

    • Marked as answer by AngryJ Monday, May 18, 2020 7:19 PM
    Friday, May 15, 2020 8:41 PM

All replies

  •  1 copy if newer unless you sometimes change your machine time into the future.

    2 nope. the C++ way to reference a dll is to include headers then link to a lib 

    3 nope. the header files from the SDK should already done that. 

    4 nope see 3. 

    5 you include the header files that comes with the dll. the linker should resolve calls to APIs to dll entry points based on the lib that comes with the dll.

    6 no, the way you use it is through implicit pinvoke, see 5

    7 yes it needs to be the same between caller and callee. Since source code of the dll is not available you have to guess. it is most likely the default on both ends though. 

    8 nope, you got the lib file already, no need of LoadLibrary.

    9 yes, see 8

    10 yes, your wrapper must target the same architecture or it cannot load the API DLL. 

    11 nope. since the source code is not available and only a 32 bit of the SDK is available, your wrapper cannot support 64 bit.

    12 nope, see 11. 

    13  no, you won't exposing a C++ interface in your wrapper DLL. the whole point of wrapper is to expose a CLS compliant interface that can be used by .Net languages. 

    14 yes it is your job to marshal data (that is, copy data between the native heap and the managed heap) in the wrapper dll. see https://docs.microsoft.com/en-us/cpp/dotnet/how-to-wrap-native-class-for-use-by-csharp?view=vs-2019

    15 only if the native component only has a COM interface. in your case your DLL doesn't have one.

    16 I don't see how you get around the Marshal class in there since the job of your wrapper DLL is marshalling.

    17 nope, x86 only. see 11. 



    Visual C++ MVP

    • Marked as answer by AngryJ Monday, May 18, 2020 7:19 PM
    Friday, May 15, 2020 8:41 PM
  • Thank you! With your help, and a Post-Build Event to get the API dll in the right place, my WPF app is working now.

    Monday, May 18, 2020 7:19 PM