Laden...

C++ DLL in C# nutzen ..

Erstellt von Gremmi vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.888 Views
G
Gremmi Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren
C++ DLL in C# nutzen ..

Hallo zusammen,

ich habe leider ein kleines Problem, dessen Lösung ich einfach nicht auf die Spur komme. Vielleicht habt ihr ja eine Idee ..

Ich habe ein C++-Projekt (Visual Studio 2005). Es enthält die Dateien stdafx.h, stdafx.cpp und die NeueDLL.cpp

Die CPP enthält folgendes:


#include "stdafx.h"

// This function is used to calculate the volume of a parallelepiped rectangle
int myBoxVolume(int L, int H, int W);
// This function is used to get the dimensions of a rectangular parallelepiped
// calculate the area and volume, then pass the calculated values to the
// function that called it.
extern "C" __declspec(dllexport)int BoxProperties(int Length, int Height,
                                    int Width);

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

int myBoxVolume(int L, int H, int W)
{
    return L * H * W;
}

int BoxProperties(int L, int H, int W)
{
    int A = myBoxVolume(L, H, W);
	return A;
}

Compiliert wurde es mit der Option: Eigenschaften -> Allgemein -> "/clr"

Als zweites habe ich ein C#-Projekt mit der Program.cs, zusätzlich ist die NeueDLL als Verweis eingefügt.

Program.cs


using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace DLLUser
{
    class Program
    {
        [DllImport("neuedll.dll")]        
        public static extern int BoxProperties(int L, int H, int W);

        static void Main(string[] args)
        {
            BoxProperties(10, 10, 10);        
        }        
    }    
}

Beim compilieren des C-Sharp Projektes meldet sich der LoadLocker, beim ausführen der EXE erhalte ich die "R6033"-Meldung.

Hat einer von euch irgendeinen Lösungvorschlag für mein Problem?

Gruß,
Gremmi

915 Beiträge seit 2006
vor 15 Jahren

Hrm... versuch mal


 extern "C" __declspec( dllexport ) int __stdcall BoxProperties(int Length, int Height, int Width);

Bin leider kein C++ Fachmann...

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

630 Beiträge seit 2007
vor 15 Jahren

Hallo,

probier auch mal das Attribut so zu setzen:

[DllImport("blub.dll",EntryPoint="BoxProperties",CallingConvention=CallingConvention.Cdecl)]

Sonst weis die Runtime garnicht welche Funktion Sie aus der DLL verwenden soll.

Edit:

Wenn du den Code von Andreas.May verwendest, musst du CallingConvention auf StdCall setzen.

Edit2:

Oh Sorry, habe das mit dem LoaderLock überlesen...

Gruss
tscherno

To understand recursion you must first understand recursion

http://www.ilja-neumann.com
C# Gruppe bei last.fm

3.971 Beiträge seit 2006
vor 15 Jahren

"LoadLock" beim Debuggen --> such hier mal im Forum nach LoaderLock

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

871 Beiträge seit 2005
vor 15 Jahren

Hallo,

wenn Du P/Invoke benutzt, brauchst Du die C++ Quellen nicht mit /clr übersetzen. Der Switch ist dafür gedacht, dass Du mixed Mode Assemblys erstellst welche einen Teil managed, den anderen Teil unmanaged enthalten (und diese dann als normale Referenz benutzen kannst)

Grüsse,
Egon

871 Beiträge seit 2005
vor 15 Jahren

Hallo nochmal,

ich hab ein kleines Example erstellt, welches zwei Methoden zeigt wie man auf unmanaged code zugreifen kann:* Reine Unmanaged DLL mittels P/Invoke

  • Mixed Model DLL mittels CLI

Anbei die Solution.

Grüsse,
egon

G
Gremmi Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

Hallo zusammen,

danke für eure Antworten.

Ich habe die Lösung von egrath mit dem VS2005 getestet und es lief nicht .. mit dem 08er allerdings schon. Warum auch immer, dann arbeite ich halt mit dem 08er weiter ..

Nun habe ich allerdings doch noch ein paar Fragen ..

Ich habe ein Struct, das ich gerne an C# übergeben würde ..


public struct Ziel
{
        string name;
	int position;
};


namespace TestDLL
{
	public ref class Klasse
	{	
	public:	
		Ziel GibHer();
	};

	Ziel Klasse::GibHer()
	{
		Ziel einZiel;
		
		einZiel.name = "Fritz";
		einZiel.position = 5;

		return einZiel;
	}
}

In C# versuche ich jetzt wie folgt an die Daten zu kommen:


TestDLL.Klasse daten = new TestDLL.Klasse();

Ziel meinZiel = daten.GibHer();

Leider fällt dem Compiler nur eines dazu ein:

"GibHer" wird von der Sprache nicht unterstützt.

Was mache ich falsch?

Danke für eure Hilfe ..

Gremmi

W
872 Beiträge seit 2005
vor 15 Jahren

DLLs, die nicht COM oder .NET sind, sind per Definition C und nicht C++ - ergo musst Du den Zugriff auf die C++ Funktion kapseln, indem Du eine C Funktion mit einem void Pointer als Parameter anbietest.
Der Void Pointer muss dann in das Objekt gecastet werden und dann kannst Du das Ergebnis der Funktion anbieten. Nicht elegant - ab der einzig gangbare Weg.

S
8.746 Beiträge seit 2005
vor 15 Jahren

Mir scheint, als wäre das schon wieder managed C++. Hier wird fleissig gesprungen.