|
|
| (9 intermediate revisions by 3 users not shown) |
| Line 1: |
Line 1: |
| == Anleitung für die Hinzufügen neuer Methoden in eine Modell-DLL (am Beispiel von BlueM) == | | <div style="float:left; margin-right:10px">__TOC__</div> |
| | * DLL Anbindungen |
| | ** .NET 2 FORTRAN |
| | Zum Beispiel der DLLAdapter des BlueM Pakets [[DLL-Methoden hinzufügen (.NET 2 FORTRAN)]] |
| | ** FORTRAN 2 C++ |
| | Zum Beispiel die Anbindung des GueteModells an BlueM-Core [[DLL-Methoden hinzufügen (FORTRAN 2 C++)]] |
|
| |
|
| === Hinzufügen der neuen Methode in der BlueM Fortran-DLL ===
| |
|
| |
|
| <fortran>
| | [[Kategorie:Hilfe]] |
| logical function GetModelDescription(Description)
| | [[Kategorie:BlueM.Sim Development]] |
| !DEC$ ATTRIBUTES DLLEXPORT :: GETMODELDESCRIPTION
| | [[Kategorie:Fortran]] |
| character(*) Description
| |
| ...
| |
| end function
| |
| </fortran>
| |
| * Funktionsname und DLLEXPORT-Name müssen gleich sein !
| |
| * Übergabeparameter müssen definiert sein (und die Typen sollten so einfach wie möglich sein) !
| |
| | |
| | |
| ; Tip : Kontrollieren, ob der Export funktioniert hat, kann man mit dem DependencyWalker des Visual Studios -> "Programme\Microsoft Visual Studio 8\Common7\Tools\Bin\Depends.Exe". <br/>Dort werden alle exportierte Methoden aufgelistet.
| |
| | |
| | |
| === Erweiterung des DLL-Wrappers (C#) ===
| |
| Die Methoden der DLL werden aus der Klasse <code>DLLMethoden</code> aufgerufen.
| |
| | |
| # Hinzufügen des Delegats in DLLMethoden
| |
| # Hinzufügen der Schnittstellenmethode
| |
| # Hinzufügen einer Testmethode [[UnitTest]]
| |
| | |
| | |
| <csharp>
| |
| public class DLLMethoden
| |
| {
| |
| ...
| |
| delegate bool GetModelDescriptionDelegate([MarshalAs(UnmanagedType.LPStr)] StringBuilder description, uint length);
| |
| ...
| |
| public bool GetModelDescription(StringBuilder description, uint length)
| |
| {
| |
| if (myDll == IntPtr.Zero)
| |
| InitializeMyDll(pathToDll);
| |
| IntPtr pProc = DllImportDynamic.GetProcAddress(myDll, "OPENMI_mp_GETMODELDESCRIPTION");
| |
| GetModelDescriptionDelegate cpv = (GetModelDescriptionDelegate)Marshal.GetDelegateForFunctionPointer(pProc, typeof(GetModelDescriptionDelegate));
| |
| return cpv(description, (uint)description.Length);
| |
| }
| |
| ...
| |
| }
| |
| </csharp>
| |
| | |
| ===== Delegate =====
| |
| Eine Delegatmethode ist eine Art "Platzhalter". in diesem Beispiel fungiert sie als Platzhalter für die Fortran-DLL. Sie hat die selben Übergabeparameter wie in der Fortran-DLL beschrieben - Ausnahme sind Zeichenketten [[#Marshaling| (Siehe Marshaling)]].
| |
| | |
| ===== Marshaling =====
| |
| * Um Typensicherheit zu gewährleiseten, gibt es in .NET die Attributsklasse "MarshalAs". Über diese Klasse können Typen aus unmanaged Code und dem .Net Code ausgetauscht werden - z.B. <code>r8</code> und <code>double</code> oder wie bei <code>GetModelDescriptionDelegate</code> eine Zeichenkette (<code>LPStr</code>/<code>StringBuilder</code>):
| |
| <csharp> [MarshalAs(UnmanagedType.LPStr)] StringBuilder description </csharp>
| |
| * Um eine Zeichenkette mit der Fortran-DLL auszutauschen, muss zu dem inhalt immer auch die Länge des Strings angegeben werden:
| |
| <csharp> uint length </csharp>
| |
| | |
| ===== Aufruf der DLL-Methode =====
| |
| <csharp>IntPtr pProc = DllImportDynamic.GetProcAddress(myDll, "OPENMI_mp_GETMODELDESCRIPTION");</csharp>
| |
| Holt sich die Einsprungadresse der DLL_Methode.
| |
| <csharp>GetModelDescriptionDelegate cpv = (GetModelDescriptionDelegate)Marshal.GetDelegateForFunctionPointer(pProc, typeof(GetModelDescriptionDelegate));</csharp>
| |
| Die Einsprungadresse und der "Platzhalter" werden miteinander verknüpft. Nun kann man einfach die Delegatmethode mit den entsprechenden Parametern aufrufen:
| |
| <csharp>cpv(description, (uint)description.Length);</csharp>
| |
| | |
| | |
| | |
| [[Kategorie:OpenMI]]
| |
| [[Kategorie:Hilfe|D]] | |
| [[Kategorie:Guides]] | |
| [[Kategorie:BlueM]] | |
Zum Beispiel der DLLAdapter des BlueM Pakets DLL-Methoden hinzufügen (.NET 2 FORTRAN)
Zum Beispiel die Anbindung des GueteModells an BlueM-Core DLL-Methoden hinzufügen (FORTRAN 2 C++)