C# dll in C++ benutzen mithilfe von C++/CLI
-
Hallo CppCommunity,
ich habe seit bereits 2 Tagen ein Problem an dem ich hänge.
Und es geht einfach nicht vorran, das macht mich etwas verrückt.
Von daher wende ich mich an euch und hoffe auf Hilfe.Mein Ziel ist "theoretisch" ganz einfach,
ich versuch mein Denkansatz in ein paar wenigen Schritten zu erläutern:1.) Eine kleine Klasse (z.B. mit den Methoden 'int Addieren(int a, int b) {}' und 'int Subtrahieren(int a, int b) {}') in C# bauen...
-> Dazu hab ich in MVS immer die "New Project -> Visual C# -> Class Library" gewählt.
Am Ende ist sowas wie ein "Calculator.dll" entstanden.Code zu Step 1.):
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CSharpCalculate { public class Calc { public int Add(int a, int b){return a + b;} public int Sub(int a, int b){return a - b;} public int Mult(int a, int b){return a * b;} public int Div(int a, int b){return a / b;} } }
2.) "Add Project -> Visual C++ -> CLR -> Class Library" gewählt...
In dieser Klasse habe ich dann die "Calculator.dll" genutzt.
Dieser Schritt dient sozusagen nur als Schnittstelle (Wrapper) um meine C#-Funktionen in meinem "native" C++ Code nutzen zu können.
Daraufhin ist z.B. "CalculatorWrapper.dll" entstandenHeader-file zu Step 2.):
#pragma once #ifdef CSharpCalculate_EXPORTS #define CSharpCalculate_API __declspec(dllexport) #else #define CSharpCalculate_API __declspec(dllimport) #endif namespace CSharpCalculateWrapper { class CSharpCalculate_API CalcWrapper { public: int Add(int a, int b); int Sub(int a, int b); int Mult(int a, int b); int Div(int a, int b); }; }
C++/CLI-file zu Step 2.):
#include "CSharpCalculateWrapper.h" using namespace System; //weiß nicht genau wofür man System braucht using namespace CSharpCalculateWrapper; using namespace CSharpCalculate; int CalcWrapper::Add(int a, int b) { Calc^ c = gcnew Calc(); return c->Add(a, b); } int CalcWrapper::Sub(int a, int b) { Calc^ c = gcnew Calc(); return c->Sub(a, b); } int CalcWrapper::Mult(int a, int b) { Calc^ c = gcnew Calc(); return c->Mult(a, b); } int CalcWrapper::Div(int a, int b) { Calc^ c = gcnew Calc(); return c->Div(a, b); }
- "Add Project -> Visual C++ -> Console Application" gewählt...
Diese enthält eine Main Methode(C++), in welche ich die "CalculatorWrapper.dll" einbinden möchte, um dessen Methoden "Addieren(..) und Subtrahieren(..)" nutzen zu können...
Am Ende will ich in der Main eig. nur eine kleine Berechnung machen(mit den 2 Methoden) und dann auf der Console ausgeben.
Main-file zu Step 3.):
#include <iostream> #include "CSharpCalculateWrapper.h" using namespace CSharpCalculateWrapper; int main() { CalcWrapper* cW = new CalcWrapper(); int result = cW->Add(1, 2); std::cout << "Result: " << result << std::endl; system("pause"); delete cW; return 0; }
WARUM DAS ALLES?
Nun Falls ihr wissen wollt warum ich das alles brauche.
Und zwar weil mein Hauptprogramm nur in C++ geschrieben ist und ich gerne einen "Microsoft Word DOCX Writer" in mein Programm einfügen würde, jedoch ist die "Open XML SDK"(Kann aus Code eine *.docx-Datei erstellen) nur für C# zugänglich...
Dieses 'TestProjekt' (wie oben beschrieben) dient lediglich nur dazu, mich in die Thematik einzuarbeiten... aber schon das hindert mich seit zwei Tagen und ich mache mich allmählich verrückt deswegen.Kleine Anmerkung noch: Meine C++ Kenntnisse sind zwar nicht perfekt, aber schon relativ gut... und C# habe ich bis vor 1ner Woche eig. noch nie gehabt (aber dafür schon viel Java)... und von daher tu ich mir bis jetzt nicht so schwer mit C#, weil ich es als ein Mix von C++/Java empfinde
Ich würde mich sehr freuen über eure Hilfe, bin inzwischen sehr verzweifelt
regards
Kizane28
- "Add Project -> Visual C++ -> Console Application" gewählt...
-
Sieht doch eigentlich gar nicht so verkehrt aus, auch wenn noch Verbesserungspotential erkennbar ist.
Allerdings kann ich keine konkrete Frage entdecken. Funktioniert etwas nicht oder bist du einfach so ein wenig am Verzweifeln?
-
Hey sorry,...
also ich hätte gedacht mein Code ist falsch.
Bzw. irgendwas fehlt da noch.
ja es geht nicht, da mir nach dem Compilieren MVS sagt, dass
er die funktionen Add(), Sub()... usw. nicht findet.
(sprich sowas wie ein linker fehler)
-
Dann poste hier die exakte Fehlermeldung. Das hilft am meisten weiter.
-
Also wenn ich die Solution baue meldet mir Visual Studio folgenden Fehler:
Link:
3>CppNativeCalculateTest.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: int __thiscall CSharpCalculateWrapper::CalcWrapper::Add(int,int)" (__imp_?Add@CalcWrapper@CSharpCalculateWrapper@@QAEHHH@Z) referenced in function _main
3>D:\CppCLIbridgeProject\CppNativeCalculate\Debug\CppNativeCalculate.exe : fatal error LNK1120: 1 unresolved externals
-
Du musst zu deinem Test-Programm (dort wo das main() drin steht) noch die *.lib der CSharpCalculateWrapper-DLL dazulinken. Das musst du bei den Linkersettigs des Test-Programms eintragen.
-
Das hatte ich bereits getan, sieht so bei mir aus:
CppNativeCalculate(ProjProperties)->Linker->Input
->CSharpCalculateWrapper.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)Vorab vielen Dank theta!
-
Dann würde ich mit dem Dependency Walker gucken, ob die DLL tatsächlich die entsprechenden Funktionen exportiert. Wenn nein: fehlt ev. CSharpCalculate_EXPORTS?
Wenn ja: Alles nochmals sauber builden, dann die auf die richtige *.lib verweisen
-
Dankeschön.
Habe das Tool noch gar nicht gekannt,
werde ich jetzt garantiert austesten!
-
Ich habe so zufällig ein OpenSource - Project inkl. Tutorial
für genau dieses Thema gefunden://Tutorial
http://harinadha.wordpress.com/2011/10/17/ximucppapi///Github link
https://github.com/Harinadha/xIMUcppAPI--> sehr gut erklärt, wer ebenfalls Interesse hat diesen
"Using C# .NET ClassLibrary(DLL) in C/C++" zu lernen
kann ichs nur empfehlen.So verabschiede ich mich
Und nochn push kriegt dieser Beitrag von mir!