2010-06-08 35 views
5

Obtuve un dll C++ que debe integrarse en un proyecto C#.Usando C++ DLL en el proyecto C#

Creo que encontré la forma correcta de hacerlo, pero llamar al dll me da este error: System.BadImageFormatException: Se intentó cargar un programa con un formato incorrecto. (Excepción de HRESULT: 0x8007000B)

Ésta es la función en la DLL:

extern long FAR PASCAL convert (LPSTR filename); 

Y este es el código que estoy usando en C#

namespace Test{ 
public partial class Form1 : Form 
{ 
    [DllImport("convert.dll", SetLastError = true)] 
    static extern Int32 convert([MarshalAs(UnmanagedType.LPStr)] string filename); 

    private void button1_Click(object sender, EventArgs e) 
    { 
     // generate textfile 
     string filename = "testfile.txt"; 

     StreamWriter sw = new StreamWriter(filename); 
     sw.WriteLine("line1"); 
     sw.WriteLine("line2"); 
     sw.Close(); 

     // add checksum 
     Int32 ret = 0; 
     try 
     { 
      ret = convert(filename); 

      Console.WriteLine("Result of DLL: {0}", ret.ToString()); 
     } 
     catch (Exception ex) 
     { 
      lbl.Text = ex.ToString(); 
     } 
    } 
}} 

Cualquier ideas sobre cómo proceder ¿con este?

Muchas gracias, Frank

Respuesta

4

tratar de utilizar __stdcall (o WINAPI o APIENTRY) en la función exportada de la DLL.

+0

Él ya lo tiene. De WinDef.h '#define PASCAL __stdcall' –

+0

Tengo que usar el dll" tal cual "... no se permiten cambios – Frank

+0

Hay diferentes declaraciones de PASCAL en diferentes encabezados (también en WinDef.h), pero el uso dícil de' __stdcall' siempre se interpretará de la misma manera – Oleg

4

intenta cambiar su código C# desde Cualquier CPU a x86 (de diálogo Propiedades).

+0

mismo resultado ... System.BadImageFormatException: Se intentó cargar un programa con un formato incorrecto.(Excepción de HRESULT: 0x8007000B) – Frank

+1

@Frank: La excepción apunta a una falta de coincidencia x86/x64 en el código DLL y C#. Si el código de C++ se compila como x64, intente configurar el código de C# también para x64 (y viceversa si el código es x86). Al tratar con DllImport, esa es solo la causa de esa excepción (según la documentación de Microsoft - http://msdn.microsoft.com/en-us/library/system.badimageformatexception.aspx). –

4

Su función exportada usa la convención de llamadas PASCAL, que en Windows es la misma que stdcall. El tiempo de ejecución .Net necesita saber acerca de eso, por lo que modificar C# método de firma de la siguiente manera:

[DllImport("convert.dll", SetLastError = true, CallingConvention=CallingConvention.StdCall)] 
static extern Int32 convert([MarshalAs(UnmanagedType.LPStr)] string filename); 
+0

había una) demasiado en la primera línea, de modo eliminado esta: [DllImport ("convert.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)] extern estático Int32 convertir ([MarshalAs (UnmanagedType.LPStr)] string nombre de archivo); pero sigue siendo el mismo error System.BadImageFormatException: Se intentó cargar un programa con un formato incorrecto. (Excepción de HRESULT: 0x8007000B) – Frank

+1

Puede dar más detalles sobre su plataforma, la configuración del proyecto y la DLL utilizada. (Arquitectura x86/x64, etc.) –

0

dos pasos principales son

1- Creación de un C++ DLL

En Visual Studio

**New->Project->Class Library** in c++ template Name of project here is first_dll in visual studio 2010. Now **declare your function as public** in first_dll.h file and write the code in first_dll.cpp file as shown below. 

Header File

Cpp File

Check **Project-> Properties -> Configuration/General -> Configuration Type** 
this option should be **Dynamic Library(.dll)** and build the solution/project now. 

first_dll.dll archivo se crea en la carpeta de depuración

2- La vinculación en proyecto de C#

Open C# proyecto

Rightclick on project name in solution explorer -> Add -> References -> Browse to path 
where first_dll.dll is created and add the file 

añadir esta línea en la parte superior de C# proyecto

Using first_dll; 

Ahora presentar se puede acceder mediante el siguiente comunicado en alguna función

double var = Class1.sum(4,5); 

he vinculado el proyecto C++ DLL creada en VS2010 a C# proyecto creado en VS2013. Funciona bien.