2010-06-08 7 views
5

J'ai reçu une DLL C++ qui doit être intégrée dans un projet C#.Utilisation de la DLL C++ dans le projet C#

Je pense que j'ai trouvé la bonne façon de le faire, mais l'appel de la DLL me donne cette erreur: System.BadImageFormatException: Une tentative a été faite pour charger un programme avec un format incorrect. (Exception de HRESULT: 0x8007000B)

Ceci est la fonction de la dll:

extern long FAR PASCAL convert (LPSTR filename); 

Et voici le code que je utilise 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(); 
     } 
    } 
}} 

Toutes les idées sur la façon de procéder avec ça?

Merci beaucoup, Frank

Répondre

4

essayez d'utiliser __stdcall (ou WINAPI ou APIENTRY) dans la fonction exportée de la DLL.

+0

Il a déjà. De WinDef.h '#define PASCAL __stdcall' –

+0

Je dois utiliser le dll" tel quel "... aucun changement autorisé – Frank

+0

Il existe différentes déclarations de PASCAL dans différents en-têtes (également dans WinDef.h), mais l'utilisation dierct de' __stdcall' sera toujours interprété de la même manière – Oleg

4

Essayez de changer votre code C# de AnyCPU à x86 (dans le dialogue Propriétés).

+0

même résultat ... System.BadImageFormatException: Une tentative de chargement d'un programme avec un format incorrect a été effectuée.(Exception de HRESULT: 0x8007000B) – Frank

+1

@Frank: Les points d'exception à incompatibilité x86/x64 dans le code DLL et C#. Si le code C++ est compilé en tant que x64, essayez de définir également le code C# sur x64 (et vice-versa si le code est x86). Lorsque vous traitez avec DllImport, ce n'est qu'une cause pour cette exception (selon la documentation Microsoft - http://msdn.microsoft.com/en-us/library/system.badimageformatexception.aspx). –

4

Votre fonction exportée utilise la convention d'appel PASCAL, qui dans Windows est la même que stdcall. Le moteur d'exécution .Net a besoin de savoir à ce sujet, afin de modifier votre C# signature de la méthode comme suit:

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

il y avait un) trop à la première ligne, ainsi enlevé ceci: [DllImport ("convert.dll", SetLastError = vrai, CallingConvention = CallingConvention.StdCall)] statique extern Int32 convert ([MarshalAs (UnmanagedType.LPStr)] nom de fichier de la chaîne); mais toujours la même erreur System.BadImageFormatException: Une tentative de chargement d'un programme avec un format incorrect a été effectuée. (Exception de HRESULT: 0x8007000B) – Frank

+1

Pouvez-vous donner plus de détails sur votre plate-forme, les paramètres du projet et la DLL utilisée. (Architecture x86/x64 etc) –

0

Deux principales étapes sont

1- Création d'un C++ dll

Dans 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 fichier est créé dans Debug

2- Lier en C# projet

ouvert C# projet

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

Ajoutez cette ligne en haut en Projet C#

Using first_dll; 

fichier maintenant peut être consulté en utilisant ci-dessous déclaration dans une fonction

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

Je lié le projet C++ .dll créé en VS2010 pour projet C# créé en VS2013. Ça marche bien.

Questions connexes