none
Using unmanaged C++ dll in managed C#

    Question

  • Hello!

    I've used Visual Studio 2012 to create an unmanaged C++ dll as described in http://msdn.microsoft.com/en-us/library/vstudio/ms235636.aspx:

    // FileArchitecture.h
    #include <Windows.h>
    #include <winnt.h>
    #include <DbgHelp.h>

    #ifdef FILEARCHITECTURE_EXPORTS
    #define FADLL_API __declspec(dllexport)
    #else
    #define FADLL_API __declspec(dllimport)
    #endif

    namespace KRGJ
    {
    namespace kernel32
    {
    class FileArchitecture
    {
    public:
    static FADLL_API WORD getMachineType( LPTSTR fileName );
    };
    }
    }

    // FileArchitecture.cpp : Defines the exported functions for the DLL application.
    //

    #include "stdafx.h"
    #include <Windows.h>
    #include <winnt.h>
    #include <DbgHelp.h>
    #include "FileArchitecture.h"

    using namespace std;

    namespace KRGJ
    {
    namespace kernel32
    {
    WORD FileArchitecture::getMachineType( LPTSTR fileName )
    {

    ... implementation details unimportant...

    }

    }

    }

    I then have attempted to access the getMachineType() function in a different C# solution/project just to test it:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;

    namespace GetArch
    {
        class Program
        {

            [DllImport("FileArchitecture.dll", SetLastError = true, CharSet = CharSet.Auto)]
            public static extern UInt16 getMachineType([MarshalAs(UnmanagedType.LPTStr)] string file);

            static void Main(string[] args)
            {
                string fileName = @"C:\...\FileArchitecture.dll";  (truncated path)
                UInt16 mach = (UInt16)getMachineType(fileName);

     ... implementation unimportant...
            }
        }
    }

    the problem is that as soon as I try to run the test program, I get an EntryPointNotfoundException - Unable to find an entry point named getMachineType in DLL FileArchitecture.dll.

    I've physically copied the FileArchitecture.dll into the directory where the GetArchTest is compiled so it is finding the DLL, but not the entry point.  What have I done wrong?

    Thanks,

    Kenn

    Friday, August 30, 2013 4:22 PM

Answers

All replies

  • You need a non-class function, and need to export/define it with extern "C".  Also, realize that (by default) the calling convention in VC++ is cdecl, but the default PInvoke is stdcall - so you'll need to use CallingConvention=CallingConvention.Cdecl in the DllImport attribute, as well.


    Reed Copsey, Jr. - http://reedcopsey.com - If a post answers your question, please click Mark As Answer on that post. If you find a post helpful, please click Vote as Helpful.

    Friday, August 30, 2013 4:30 PM
  • Thanks!  Both for the quick reply and for the solution!

    Just in case anyone else (or I, myself) should ever read this post in the future (you know the internet, it'll be out here forever) I took Mr. Copsey's advice and did the following:

    1) Got rid of all the 'class' stuff in the FileArchitecture DLL; it wasn't wanted or needed.

    2) changed my call in the File Architecture DLL to (essentially) "__declspec(dllexport) WORD __stdcall getMachineType( LPTSTR fileName)".  The __declspec(dllimport) I still put in via the #ifdef sequence; the __stdcall was so my function used the standard calling convention (because I may use this function in the future and don't want to have to remember to modify my DllImport statement every time I use it).  Besides, stdcall is just the right thing to do (especially in 64-bit).

    3) Wrapped my function prototype in "extern "C" {}".  This was so the compiler doesn't mangle the name of the function; evidently, the compiler routinely mangles the name to something illegible (looking at my lib file, it was something of the nature of "getMachineType@@kernel32@@FileArchitecture" or something similar) to the human eye; using extern "C" stops the compiler from doing that.

    Thanks again!

    Friday, August 30, 2013 7:25 PM