Array aus einer C++ DLL auslesen und in C# Anzeigen lassen



  • Hallo
    habe ein Problem: Wie kann ich ich aus einer C++ DLL ein Array auslesen und in C# Anzeigen lassen?

    Das mit dem allgemeinen DLLexport/ inport habe ich in folgendem Programm schon hinbekommen:

    C++ DLL

    // TestDLL.cpp : Defines the exported functions for the DLL application.
    //
    
    #include "stdafx.h"
    #include <math.h>
    #include <iostream>
    
    using namespace std;
    
    extern "C" __declspec(dllexport)void umrechnung(double rscp_in_dbm, double &rscp_in_w);
    
    BOOL APIENTRY dllmain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        return TRUE;
    }
    
    void umrechnung(double rscp_dbm, double &rscp_w)
    {
    	double temp = 0.0;
    	temp =(rscp_dbm/10);
    	rscp_w = (pow (10, temp))*0.001;
    	cout << "\nUmrechnung in C++ DLL" << endl;
    }
    

    C# Code

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices; 
    
    namespace log_berechnung
    {
        class MeineDLL      
        {
            [DllImport("testdll.dll")]
            public static extern bool umrechnung(double rscp_dbm, out double rscp_w);
        }
    
        class Program
        {
            static void Main()
            {
                double rscp_in_dbm = 0.0;
                double rscp_in_w=0.0;
    
                Console.WriteLine("Umrechnung von dBm nach Watt");
                Console.Write("Eingabe in dBm: ");
                rscp_in_dbm = Convert.ToDouble(Console.ReadLine()); // Eingabe
    
                MeineDLL.umrechnung(rscp_in_dbm, out rscp_in_w); // Aufruf der C++ DLL
    
                Console.WriteLine("\nErgebnis in [W]: " + rscp_in_w);
    
                Console.ReadLine(); // Beenden der Konsole
            }
        }
    }
    

    Wie gesagt jetzt möchte ich versuchen ein Array in C++ zu erstellen und in C# mir Anzeigen zulassen. Das bekomme ich einfach nicht hin 😞
    Könnte mir einer sagen wie man das am besten machen kann?

    PS: Ich verwende VS 2008


  • Administrator

    1. Verwende in einer exportierten Funktion keine Referenzen sondern Zeiger! C# geht davon aus, dass es sich um eine C Funktion handelt und in C gibt es keine Referenzen. Sowas kann böse ins Auge gehen.
    2. Du exportierst als __cdelc und importierst als __stdcall ! Du musst die richtige Aufrufkonvention in C# angeben mit dem Parameter CallingConvention von DllImportAttribute .
    3. Wer soll denn den Speicher des Arrays wieder freigeben? Und was für Objekte sind im Array gespeichert? Double?

    Grüssli



  • Ich glaube ich habe es soweit hin bekommen

    // TestDLL.cpp : Defines the exported functions for the DLL application.
    //
    
    #include "stdafx.h"
    #include <math.h>
    #include <iostream>
    
    using namespace std;
    
    extern "C" __declspec(dllexport)void main(double feld[], double &wieviel);
    
    BOOL APIENTRY dllmain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
        return TRUE;
    }
    
    void main(double feld[], double &wieviel)
    {
    	cout << "Array in C++ DLL\n" << endl;
    	cout << "Wieviele Eingaben? " ;
    	cin >> wieviel;
    
    	for(int i=0; i <wieviel; i++)
    	{
    		cout << "Feldnr. " << i << " eingeben: ";
    		cin >> feld[i];
    	}
    }
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace array
    {
        class MeineDLL
        {
            [DllImport("testdll.dll")]
            public static extern bool main(out double feld, out double wieviel);
        }
    
        class Program
        {
            static void Main()
            {
                double wieviel=0; // größe von array
                double[] feld = new double[100];
                double erg = 0;
    
                MeineDLL.main(out feld[0],out wieviel); // Aufruf der C++ DLL    
    
                Console.WriteLine(wieviel);
    
                int test = System.Convert.ToInt32(wieviel);
    
                // Neues Array mit der richtigen größe
                double[] temp = new double[test];
    
                // Kopiere Arrays 
                for (int x = 0; x < test; x++)
                {
                    temp[x] = feld[x];
                }
    
                feld = null; // spiecherplatz freigeben
                GC.Collect(); 
    
                for (int x=0; x<temp.Length; x++)
                {
                    Console.WriteLine("Array in C#: " + temp[x]);
                }
    
                erg = temp[2] + 10;
                Console.WriteLine("Feld[2] + 10 = " + erg);
                Console.ReadLine(); // Beenden der Konsole
    
                temp = null; // spiecherplatz freigeben
                GC.Collect();
            }
        }
    }
    

    Habe einige fragen:
    [] Wie kann ich das Array feld in einer dynamischen grösse angeben?
    [
    ] Mit dem Speicherplatz freigeben : Ist das so richtig oder gibt es in C# eine bessere Methode?


  • Administrator

    Hast du meinen Beitrag überhaupt gelesen? Geh mal auf meine Fragen ein und ich kann dir auf der Stelle helfen. Was du als "Lösung" "gefunden" hast, ist schrecklich. Da hat jemand einfach wild herumprobiert und fertig, statt dass er sich mit der Materie befasst hat.

    Edit:
    Eine zusätzliche Frage wäre vielleicht noch, was du überhaupt als übergeordnetes Ziel hast? Was willst du erreichen?

    Grüssli


Anmelden zum Antworten