Aldemar Cuartas Carvajal
Aldemar Cuartas Carvajal

Reputation: 2391

.NET C# problems calling C++ Native Win32 DLL

My C++ DLL source code is:

#include "stdafx.h"
#include "LicensePolicy.h"

std::string GetLicense()
{
    DWORD dwType = REG_SZ;
    HKEY hKey = 0;
    char value[1024];
    DWORD value_length = 1024;
    LPCWSTR subkey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WSESecurityPolicy";
    LONG openReg = RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0, KEY_WOW64_64KEY | KEY_QUERY_VALUE, &hKey);
    if (openReg==ERROR_SUCCESS)
    {
    }
    else
    {
        return "ERROR: No pudo abrir la ruta del registro";
    }

    LONG getReg = RegQueryValueEx(hKey, L"WSEHostProcessID", NULL, &dwType, (LPBYTE)&value, &value_length);
    if (getReg==ERROR_SUCCESS)
    {
        return std::string(value);
    }
    else
    {
        return "ERROR: No pudo obtener el valor del registro";
    }
}

std::string GetXmlTokenNode()
{
    std::string result = GetLicense();
    if (result == "ERROR: No pudo abrir la ruta del registro" ||
        result == "ERROR: No pudo obtener el valor del registro")
    {
        std::ofstream myfile;
        myfile.open ("punto2.txt");
        myfile << result;
        myfile.close();
        return std::string("");
    }
    else
    {
        std::ofstream myfile;
        myfile.open ("punto1.txt");
        myfile << "Valor:" << result;
        myfile.close();
    }

    return std::string("/{0}:Envelope/{0}:Header");
}

This DLL is compiled by using name: LicensePolicy.dll

Definition File:

LIBRARY

MODULE "LicensePolicy" EXPORTS GetXmlTokenNode @1

C# TestDllConsole to test DLL is as follows:

using System.Runtime.InteropServices;
using System.ComponentModel;

namespace TestDllConsoleApplication
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Test testObj = new Test();
        }
    }

    public class Test
    {
        [DllImport("LicensePolicy.dll", CharSet = CharSet.Unicode)]
        public static extern string GetXmlTokenNode();

        public Test()
        {
            try
            {
                string result = GetXmlTokenNode();
                result += " result";
            }
            catch (DllNotFoundException exDll)
            {
                string error = "Dll no encontrado";
            }
            catch (BadImageFormatException exBad)
            {
                string error = "Plataforma Ensamblado incompatible";
            }
            catch (Win32Exception exWin32)
            {
                string error = "Error general de Win32";
            }
            catch (Exception ex)
            {
                string error = "Error otros";
            }
        }
    }
}

My problem is I don't know why when GetXmlTokenNode(); method in C# is executed, inmediately C# TestConsole exits without get results from DLL. However tracing DLL by using text files, is well executed.

Thanks for yor soon help!

Aldemar

Upvotes: 1

Views: 366

Answers (1)

Will Dean
Will Dean

Reputation: 39500

I'd be surprised if you could reliably return a std::string across this sort of boundary. C++ objects are often difficult candidates for passing across API boundaries, because of uncertainty who and what manages the allocation / deallocation.

I always do interop between C# and C++ in a very 'c-like' fashion, all char* and size_t, partly because the vast body if interop examples are with the Win32 API, which is C and not C++.

For this type of string returning, I'd make the c++ function take a char* and a size_t, and from the C# side I'd pass it an StringBuilder with space reserved within it.

Upvotes: 2

Related Questions