Ich/wir haben derzeit ein Programm in Delphi (XE, speziell) geschrieben, die Schnittstellen mit einer nicht verwalteten DLL (geschrieben in C++, von dem, was ich höre). Die Delphi-Anwendung wird außer Kraft gesetzt, aber die Notwendigkeit, mit der nicht verwalteten DLL zu arbeiten, bleibt bestehen, so dass eine C# -Schnittstelle geschrieben werden muss. Keine große Sache. Abgesehen davon, dass ich keinen Zugriff auf die Quelle der DLL oder irgendeine gute Dokumentation dazu habe, und dies ist mein erster Ausflug in die Interoperabilität, bringt mich um.Konvertieren von Delphi Nicht-COM-DLL-Schnittstelle zu C#
Hier ist die Dokumentation über die verfügbaren Funktionen in der DLL:
extern EXTERNC __declspec(dllexport) long initiate (
double conc1,
double conc2,
long temp,
const char* NT
);
extern EXTERNC __declspec(dllexport) long DoWork (
long NumItems,
struct Structure* Items
);
In Delphi, diese wie dies erfolgreich umgesetzt werden (mit der benutzerdefinierten Struktur enthielt auch):
function CustomInitialize
(
Concentration1 : double;
Concentration2 : double;
Temperature : LongInt;
const Type : PAnsiChar
) : LongInt; cdecl; external 'CustomDLL.dll' name '_initiate';
procedure DoWork
(
NumItems : LongInt;
Items : PStructure
); cdecl; external 'CustomDLL.dll' name '_DoWork';
TStructure = record
ValueName : PAnsiChar;
Value : PAnsiChar;
Status : LongInt;
ReturnVal1 : Double;
ReturnVal2 : Double;
ReturnVal3 : Double;
Temp : Double;
end;
PStructure = ^TStructure;
Beachten Sie, dass während Die DoWork-Methode scheint ein Array von Elementen aufzunehmen. Alle Implementierungen setzen NumItems auf 1 und durchlaufen das Objekt in Delphi, anstatt es an C++ weiterzuleiten.
In C# bin ich nicht einmal sicher, welches Beispiel ich veröffentlichen sollte. Ich habe seit Tagen gegoogelt und versucht, was sich wie jede Version des Codes anfühlt, die ich ausprobieren kann, aber alles ohne Erfolg. Hier ist die neueste Version:
namespace JunkProject
{
class Program
{
static void Main(string[] args)
{
int test = _initiate(.05, .05, 60, "1");
Console.WriteLine(test);
if (test != 1)
Console.ReadLine();
var structure = new FoldStructure() { ValueName = "Test1", Value = "TESTTESTTESTTESTTESTTESTTEST", Status = 0, ReturnVal1 = 0.0, ReturnVal2 = 0.0, ReturnVal3 = 0.0, Temp = 0.0 };
test = _DoWork(1, structure);
Console.WriteLine(structure.Value);
Console.ReadLine();
}
private const string DLL_LOCATION = "CustomDLL.dll";
[DllImport(DLL_LOCATION, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern int _initiate(double Conc1, double Conc2, int Temp, [MarshalAs(UnmanagedType.LPStr, SizeConst = 5)] string Type);
[DllImport(DLL_LOCATION, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern int _DoWork(int NumItems, [In, Out] Structure Struct);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class Structure
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string ValueName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 28)]
public string Value;
public int Status;
public double ReturnVal1;
public double ReturnVal2;
public double ReturnVal3;
public double Temp;
}
}
}
Dies bietet jedoch eine Zugriffsverletzung. Ich habe versucht, die Methodensignatur zu einem IntPtr zu machen, das schlägt fehl. Ich habe versucht, die Methodensignatur zu einem Zeiger auf die Struktur zu machen, das geht normalerweise auf jede Art und Weise schief, die ich versuche, obwohl ich nicht sicher sein kann, dass ich wirklich sehr lange auf den richtigen Weg gehämmert habe, da bin ich mir nicht sicher, was das ist. Ich denke, wenn ich herausfinden könnte, was die korrekte Methodensignatur ist, würde das einer Tonne helfen.
Auch Entschuldigung für die leichte Verschleierung der Quelle. Die DLL, die ich verwende, ist proprietär und nicht.
Präventiver Dank für jede Hilfe!
Vielen Dank!Das Array-Konzept war etwas, das ich früher ausprobiert habe, aber ich war immer noch grün in meinem Verständnis von dem, was ich tatsächlich mache, also habe ich es wahrscheinlich falsch verstanden. Diese Kommentare machen definitiv Sinn und helfen zu erklären, was mir fehlte. Ich war auf jeden Fall hin und her gegangen, aber ich steckte in einem "Hin und Her" -Programm-Albtraum fest, ohne Feedback-Mechanismus, um zu sehen, ob irgendetwas besser funktionierte. –