Calling C++ DLL from C# is ok under Windows 7 but fails under Windows 10

1.6k views Asked by At

My program calls a C++ DLL from my C# program.

The problem is that the generated executable is running fine undex Windows 7 but not under Windows 10 !?

The steps are listed below:

I compile my C++ DLL using g++ (of TDM-GCC-64) in 64 bits. I compile my C# program using Visual studio 15 and target .NET framework 4.5.2 in 64 bits.

The C++ DLL code is :

main.h

#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>

/*  To use this exported function of dll, include this header in your project.  */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C"
{
#endif

void DLL_EXPORT SomeFunction(const LPCSTR sometext);

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__

main.cpp

#include "main.h"
#include <iostream>

// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    std::cout << "TEST FROM DLL : " << sometext << std::endl;
}

The build command is : C:\TDM-GCC-64\bin\g++ -shared -o ..\TestDllCall\bin\x64\Debug\myDLL.dll -m64 -g -D BUILD_DLL -L. main.cpp

You can notice that the dll is created directly in the target directory of the c# test program (Debug in 64 bits).

The C# main program is:

Program.cs

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace TestHstLibrary
{
    class MainProg
    {
        static void Main(string[] args)
        {
            ProgramTest ProgramTest = new ProgramTest();
            ProgramTest.dllCall();
            Console.ReadKey();
        }
    }

    class ProgramTest
    {
        [DllImport("myDLL.dll", EntryPoint = "SomeFunction")]
        static extern void SomeFunction(string sometext);

        public ProgramTest() {            
        }

        public void dllCall()
        {
            Console.WriteLine("dllCall ... ");            
            try
            {
                SomeFunction("Hello !");
            } catch (Exception e)
            {
                Console.WriteLine("EXCEPTION : " + e.Message);
                Console.WriteLine(e.ToString());
            }
            Console.WriteLine("");
        }        
    }
}

Note : The build is done on the final target plateform : Win10 64bits.

Running on my Windows 10, I have the following :

dllCall ...
EXCEPTION : Unable to load DLL 'myDLL.dll': A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT : 0x8007045A) System.DllNotFoundException: Unable to load DLL 'myDLL.dll': A dynamic link library (DLL) initialization routine failed. (Exception de HRESULT : 0x8007045A) à ProgramTest.SomeFunction(String sometext) à ProgramTest.dllCall() dans C:\TestDllCall\TestDllCall\Program.cs:ligne 30

After a copy of the entire build directory from Win10 to a Win7, running it on my Win7, I have the following :

dllCall ...
TEST FROM DLL : Hello !

It's working fine.

If someone has an idea why it fails under Win10 and not under Win7, I will be pleased to have the answer.

I check with dependency walker and had the following: - Under Windows 10, some dependencies are missing even if it has been generated under Win10 - Under Windows 7, all dependencies are ok.

So I try with an other c++ compiler from g++ of TDM-GCC-64, I tested with the one from cygwin : does not give a better result, even worse.

I also try to pass my c# string parameter as a IntPtr as shown below:

IntPtr myptr = Marshal.StringToHGlobalAnsi("Hello !");
SomeFunction(myptr);

But it does not work either under Win10 but still working under Win7.

An other test was to remove the std::cout form my dll, finally the call is ok but I still want to make it work as this is in a test environment and in a production environment I will have to make it with an external dll which I don't have the source code.

1

There are 1 answers

0
Olivier On

I updated the code as below :

int DLL_EXPORT SomeFunction()
{
    return 5;
}

It was working. So called unmanaged dll from c# is ok.

After, I search about the cout, I found in stackoverflow some topic related to usage of cout in unmanaged dll called from c# ...

So after I changed again the function to the following :

void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}

The error happens again !

Then I decided after some advice while triyng to solve this problem to build the DLL with Visual Studio C++ (instead of TDM-GCC-64).

After building the DLL with MS C++ and running the test under Win10: It's working :-)

The std::cout is OK The messageBox is OK There is no more : Exception from HRESULT : 0x8007045A

Thanks a lot to people who answered.