| 

.NET C# Java Javascript Exception

2
2 Fragen zum Thema multi language programming:
1. Kann man im Visual Basic 2005 (Express) direkt C-Code einfügen (und von dort aus am Besten auf VB-Variablen zugreifen, also ähnlich wie es in VC mit Assembler geht)? Es geht hier um Performance.
2. Hat jemand Erfahrung(-swerte), welche Sprache bei dem exakt gleichen Programm wieviel schneller ist?
25.05.2011
muffi 1,4k 1 9
7 Antworten
1
Du kannst das auch mit DLL-Import machen. Du schreibst das, was zeitkritsch ist, in C++, legst die C++-DLL in das Ausführungsverzeichnis und importierst dann die Methoden. Ich habe dir ein Beispiel aus meinem Code kopiert, wo ich die Methode NeSoundStartRecording aus der NeSoundBase.dll importiere. Du kannst dann die Methode NeSoundStartRecording einfach aus dem C#-Code raus aufrufen. Und du kannst sogar passende delegates übergeben.

Ich weiß nicht, ob das eleganter oder schneller ist als mit P/Invoke, aber so machen wir das oft, und bei uns funktioniert es prima.

using System.Runtime.InteropServices; 
public unsafe delegate void CallbackDefMuxData(Int16* piBuf, uint nSamples, uint nChannels);

[DllImport("NESoundBase.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern Int32 NeSoundStartRecording
( uint uDeviceID
, CallbackDefMuxData pfCallBackMuxData // Callback für Daten (kann NULL sein)
, string sFileName
, uint uScanRate);
25.05.2011
KN 1,7k 1 8
KN 1,7k 1 8
Das ist exakt genauso elegant und schnell wie P/Invoke, denn es ist P/Invoke ;-)
"DllImport" ist nur der Name des Attributs.
Matthias Hlawatsch 25.05.2011
Ah, danke für den Hinweis. Wieder was gelernt :-)
KN 26.05.2011
1
Ganz so einfach, wie Du es Dir vorstellst, geht es leider nicht. Aber Du könntest Deine performance-kritische Routine in eine eigene DLL stecken, die Du mit C oder C++ programmierst (wenn Du nur die Express-Edition vom VS hast, wirst Du eine eigene Entwicklungsumgebung dafür brauchen). Diese DLL kannst Du dann aus Deinem VB-Projekt heraus referenzieren und über P/Invoke aufrufen. Wie das für Win32-APIs geht, ist auf pinvoke.net hevorragend dokumentiert. Außerdem wirst Du möglicherweise die PInvoker-Tools nützlich finden.
25.05.2011
Matthias Hlawatsch 13,2k 4 9
Ja, mir steht nur die Express-Edition zur Verfügung. DLLs habe ich ehrlich gesagt noch nie programmiert; dazu müsste ich also erst noch einsteigen - und damit sind wir wieder bei Platform invoke. Bleibt im Moment also höchstens übrig, Code zu optimieren. Ich muss mal darüber schlafen, ob das Problem gelöst ist.
muffi 25.05.2011
Wenn Du Dir zutraust, die fragliche Routine in "eingebettetem" C zu programmieren, sollte das Bauen einer DLL Dich vor keine unüberwindbaren Hindernisse stellen. Tutorials dazu müßte es einige im Web geben, oder Du fragst hier bei codekicker. Und solange die Datentypen von Parametern und Rückgabe nicht zu komplex sind, ist P/Invoke eigentlich ziemlich straightforward.
Matthias Hlawatsch 25.05.2011
0
- deleted -
25.05.2011
m.fuchs 1,8k 2 8
m.fuchs 1,8k 2 8
0
Hallo m.fuchs und der Rest der Welt :-)

ich meinte NICHT C#! Es handelt sich bei mir durchaus um ein größeres / großes Programm, das einige kleine Passagen zeitkritische Routinen beinhaltet. Deshalb kam mir eben die Idee, ob man C (kein C++ und auch kein C#) einbetten kann - oder ob VB2005 so effektiv kompiliert, dass das keinen (großen) Unterschied macht.

Kurzes Beispiel dazu:
C: ++x;
VB: x=x+1
...ist wahrscheinlich in C schneller als in VB - dahin ging ja auch ein Teil meiner Frage.

Ich denke, das Beispiel dürfte ziemlich genau das treffen, was ich gerne erreichen würde.
25.05.2011
muffi 1,4k 1 9
0
Also: vermutlich hast du Recht: ++x zu Native Code compiliert ist vermutlch schneller, als der von VB erzeugte IL Code, der ja VOR der Ausführung einmal auf Native Code übersetzt werden muss (ausser du arbeitest mit NGEN, dann kannst du das vorbereiten).

Du hast allerdings bei JEDEM Aufruf einer Funktion oder Methode einen Overhead zu berücksichtigen: Würdest du also eine Berechnung x=x+1 in C Code auslagern, um das performanter zu haben, hättest du über die ganzen Parameterübergabegeschichten und Sprünge mehr Zeit verloren als durch den Trick gewonnen.

Da müsstest du schon größere Teile in C auslagern.

Der Zugriff auf die VB Variablen ist das nächste Problem: Du musst verhindern, dass die Variablen auf die du aus C zugreifen willst (vor allem wenn es sich um Strings oder gleich ganze um Objekte handelt), in der Zwischenzeit vom GC angegriffen werden ... denn sonst passen dir vielleicht irgendwelche Adressen nicht mehr.
25.05.2011
nabuchodonossor 1,3k 5
0
Natürlich kommt niemand auf die Idee, eine Anweisung wie ++x; auszulagern. Bei mir geht es konkret um eine Routine, die in VB ihre 2 Tage läuft und ich das mit C gerne verkürzen wollte. Auf Objekte greife ich dabei nicht zu, aber auf Übergabewerte. Mir würde es wahrscheinlich schon helfen, wenn man in VB so etwas in der Richtung machen könnte:

private function func(parameter) as integer
[C-Code]
end sub
25.05.2011
muffi 1,4k 1 9
muffi 1,4k 1 9
0
Nachdem MS ein recht gutes Tutorial zum Erstellen einer DLL hat, überlege ich gerade, wie ich die DLL im VB dann importiere. Ich gehe davon aus, dass das wie bei anderen DLLs funktioniert? Also in der Richtung:

Aus dem Header des Treibers:
static __declspec(dllexport) int func1(char* str1, char* str2);

aus VB:
Declare Function func1 Lib "treiber.dll" (ByVal str1 As String, ByVal str2 as String) as Integer

...und dann im Code:
x = func1(stra,strb)

Die Strings haben leider keine feste Länge.
26.05.2011
muffi 1,4k 1 9
Wäre vielleicht besser, Du machst dafür eine eigene Frage auf.
Ansonsten: der C-Teil sieht auf den ersten Blick für mich ok aus. Mit VB.NET kenne ich mich nicht aus, aber von den MSDN-Beispielen her müßte es eigentlich eher so aussehen:
<DllImport("treiber.dll", CharSet:=CharSet.Auto)> _
Shared Function func1(ByVal str1 As String, ByVal str2 as String) As Integer
Matthias Hlawatsch 26.05.2011

Stelle deine Programmieren-Frage jetzt!