Hallo,
Ich möchte eine DLL einbinden, in der Hilfe ist das Einbinden einer Funktion davon wie folgt beschrieben:
[C#]
unsafe public static extern uint CAN_GetHwParam(
byte hHw,
ushort Param,
void* Buff,
ushort BuffLen
);
Hier wird ja ein Zeiger verwendet im C# Code..? Hat das was mit dem unsafe zu tun.Also C/C++ Code?
In meiner Zugriffsklasse auf die DLL habe ich folgendes definiert:
[DllImport("CANAPI2.dll", EntryPoint = "CAN_GetHwParam")]
unsafe public static extern uint GetHwParam(byte hHw, ushort Param, ref char[] Buff, ushort BuffLen);
Wenn ich diese funktion jetzt verwenden will:
ret = CanApi2.GetHwParam(0, CanApi2.PARAM_NAME, ref szBuff, Convert.ToUInt16(szBuff.Length));
Kommt die Exception:
System.ExecutionEngineException
Was habe ich falsch gemacht?
Mein zweites Problem ist das ich noch eine andere TP.DLL verwende. Dies hatte vor dem einbinden der CANAPI2.DLL funktioniert. Jetzt findet er die TP.DLL auf einmal nicht mehr..
Woran kann das jetzt liegen..?
Danke!
Unsicheren code zulassen in den Projekt eigenschaften hast du angekreuzt???
cSharp Projekte : https://github.com/jogibear9988
Ja das habe ich gemacht, weil vorher eine dementsprechende Fehlermeldung kam..
Jetzt habe ich mal die Funktion wie in der Hilfe dokumentiert deklariert:
[DllImport("CANAPI2.dll", EntryPoint = "CAN_GetHwParam")]
unsafe public static extern uint GetHwParam(byte hHw,ushort Param,void* Buff,ushort BuffLen);
kann ich hier also Zeiger verwenden, weil das unsafe Code ist?
Aber wie rufe ich die Funktion jetzt auf?
ret = CanApi2.GetHwParam(0, 0, &szBuff, Convert.ToUInt16(szBuff.Length));
Fehler 1 Zeiger und Puffer fester Größe können nur in einem unsicheren Kontext verwendet werden.
Fehler 2 Es ist nicht möglich, einen Zeiger für den verwalteten Typ ("char[]") zu deklarieren oder dessen Adresse oder Größe abzurufen.
Du benötigst sehr selten unsave für apiaufrufe.
Du hast auch den buffer vorher mit new angelegt?
unsafe
{
char[] szBuff;
szBuff = new char[CanApi2.MAX_DRIVERNAMLEN];
ret = CanApi2.GetHwParam(0, 0, &szBuff, Convert.ToUInt16(szBuff.Length));
}
So habe ich jetzt nochmal den Aufruf probiert.Jetzt kommt nur noch eine Fehlermeldungbei "&szBuff":
Fehler 1 Es ist nicht möglich, einen Zeiger für den verwalteten Typ ("char[]") zu deklarieren oder dessen Adresse oder Größe abzurufen.
Es sollte allerdings möglich seinen, einen Zeiger auf das erste Element zu übergeben:
&(szBuff[0])
Kann es gerade nicht testen, sollte aber so funktionieren.
Dust Signs
Die Nummer, die Sie gewählt haben, ist imaginär. Bitte drehen Sie Ihr Telefon um 90° und versuchen Sie es erneut.
Hallo,
Wenn ich mir die Funktion so ansehe, gehe ich einmal davon aus, dass Parameter "Buff" ein Buffer ist in den etwas geschrieben wird, welcher die Länge "BuffLen" hat.
Das ganze funktioniert auch ganz ohne unsafe code:
[DllImport("CANAPI2.dll", EntryPoint = "CAN_GetHwParam")]
public static extern uint GetHwParam(byte hHw, ushort Param, byte[] Buff, ushort BuffLen);
...
const int buffLength = 1024;
byte[] buffer = new buffer[buffLength];
uint result = GetHwParam(0, 0, buffer, buffLength);
...
Ob die Funktion bytes, shorts, ect erwartet musst du der API entnehmen.
Spooky
@Dust:
unsafe
{
char[] szBuff;
szBuff = new char[CanApi2.MAX_DRIVERNAMLEN];
ret = CanApi2.GetHwParam(0, 0, &(szBuff[0]), Convert.ToUInt16(szBuff.Length));
}
liefert:
Fehler 1 Sie können nur die Adresse eines unfixed-Ausdrucks innerhalb eines fixed-Anweisungsinitialisierers abrufen.
@Spook:
uint ret=0;
const int buffLength = 1024;
byte[] buffer;
buffer= new byte[buffLength];
ret = CanApi2.GetHwParam(0, 0, buffer, buffLength);
So klappt der Aufruf jetzt (auch ohne unsafe wie in deinem Beitrag)!
Was ist jetzt aber mit meinem zweiten Problem..Woran könnte das liegen das die andere DLL aufeinmal nicht mehr gefunden wird. Hatte Die auch neu erstellt und nochmal reinkopiert in den Projektordner..
DllImport("CANAPI2.dll", EntryPoint = "CAN_GetHwParam")]
public static extern uint GetHwParam(byte hHw, ushort wParam, [Out] byte[] pBuff, ushort wBuffLen);
const int buffLength = 1024;
byte[] buffer = new buffer[buffLength];
uint result = CanApi2.GetHwParam(0, CanApi2.PARAM_NAME, buffer, buffLength);
Das [Out] ist wichtig, sonst "siehst" du das Ergebnis nicht.
Und es sollte schon byte[] sein und nicht char[]. Da können ja schließlich auch andere Sachen als Strings zurückkommen. Zudem ist ein char=2bytes groß.
beste Grüße
zommi
Hallo,
das out ist nicht nötig, da .NET den Zeiger auf das erste Array-Element übergibt und die Daten direkt in dieses geschrieben werden (genau das, was vorher manuell mit unsafe erreicht werden sollte).
Spooky
das out ist nicht nötig
Stimmt, mein Fehler.
Ich würds vielleicht trotzdem hinschreiben. Zeigt's nochmal auf, dass das was zurückkommt.
beste Grüße
zommi
Hat jemand eine Idee warum die andere DLL jetzt nicht mehr gefunden wird (DLLNotFoundException)?