Forum: PC-Programmierung Native C Code in C#


von user (Gast)


Lesenswert?

Hallo,

eine bestehende C Konsolenapplikation soll via DLL in C# eingebunden 
werden.
Diese Konsolenapplikation beinhaltet eine Empfangs-Callback-Funktion wo 
die ankommenden Daten weiter verarbeitet werden sollen. Es handelt sich 
hierbei um UDP Nachrichten. Wie wird der Empfangs-Callback-Funktion in 
der DLL verpackt so dass in C# auf diese Daten zugegriffen werden kann?

von user (Gast)


Lesenswert?

Was müsste ich tun damit die Daten in der Callbackfunktion OnRecieveCLB 
per dllexport Anweisung weitergereicht werden?
1
void OnReceiveCLB(void)
2
{
3
4
}

von Bert3 (Gast)


Lesenswert?

http://stackoverflow.com/questions/13629798/c-sharp-delegate-for-c-callback

weiter unten ist ein funktionierendes Beispiele - oder genug 
Schlüsselworte nach denen du suchen kannst

von user (Gast)


Lesenswert?

Das Empfangen von Daten funktioniert nun. Jetzt habe ich allerdings ein 
weiteres Problem. Ich möchte jetzt Daten vom Hauptprogramm generieren 
und in der Send Methode benutzen. Der Empfangspuffer von der Gegenstelle 
ist leer.
1
int test = 0;
2
3
int main(void)
4
{
5
  test = 50;
6
7
  for (int i = 0; i < 100; i++)
8
  {
9
    UdpFrameBuffer[i] = 0x34;
10
  }
11
12
  return 0;
13
}
14
15
__declspec(dllexport) void Send(void)
16
{
17
18
    UPort->Send(UdpFrameBuffer, 50);
19
}

von user (Gast)


Lesenswert?

In der Send Methode soll ein Frame erzeugt werden mit den entsprechenden 
Daten. Dieses Frame soll dann mit der UdpSend Funktion versendet werden.

von Bert3 (Gast)


Lesenswert?

Ich versteh die Frage nicht ganz - aber die erste Antwort enthaelt doch 
schon alle technischen Mitteln um einen Callback oder einen 
Funktionsaufruf zu realisieren - ansonsten google

von user (Gast)


Lesenswert?

Ich habe intern (C Code) eine Funktion mit der ich ein UDP Frame 
generiere.
Diese Funktion beinhaltet sämtliche Strukturen. Das ganze soll nur 
intern benutzt werden.

von user (Gast)


Lesenswert?

Im C Projekt gibt es eine Datei mit dem Namen Ddllmain.cpp. Wird 
überhaupt ein Einstiegspunkt void main(void) verwendet?

von Bert3 (Gast)


Lesenswert?

>Wird überhaupt ein Einstiegspunkt void main(void) verwendet?

Nein main wird nicht verwendet - das siehst du wenn du deine dll 
debuggst oder ein printf einbaust

und das kann dir auch google beantworten

von user (Gast)


Lesenswert?

Ok.

Allerdings soll in der Funktion Send bevor die Daten per UDP versendet 
werden, durch die Funktion GenerateData generiert werden. Diese Funktion 
beinhaltet ebenso weitere Funktionen sowie Strukturen.

__declspec(dllexport) void Send(void)
{
  GenerateData Data;
  GenerateFrame(&Data);
  UPort->Send((char*)&Data, sizeof(data_t));
}

von Bert3 (Gast)


Lesenswert?

>Allerdings soll in der Funktion Send bevor die Daten per UDP versendet
>werden, durch die Funktion GenerateData generiert werden. Diese Funktion
>beinhaltet ebenso weitere Funktionen sowie Strukturen.

Das ist schön - ist das jetzt eine Frage oder ein Statement?

Tips:
1. triviale Fragen mit google lösen
2. Fragen auch als Fragen formulieren - mit ?

von user (Gast)


Lesenswert?

Wenn in der Send Funktion NUR
1
  GenerateData Data;
2
  GenerateFrame(&Data);

ausgeführt wird erscheint in der C# Applikation folgende Meldung:

Fehlermeldung:

Ein Ausnahmefehler des Typs "System.AccessViolationException" ist in 
TestProgram.exe aufgetreten.

Zusätzliche Informationen: Es wurde versucht, im geschützten Speicher zu 
lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass 
anderer Speicher beschädigt ist.

von Bert3 (Gast)


Lesenswert?

Auf diese Frage gibt es keine trivial Antwort - der Fehler liegt in 
deinem Code und kann aus x Richtungen kommen - bei manage<->nativ fehlen 
die alle normalen Schutzprinzipien von .Net d.h. du erzeugt mit Unwissen 
nicht nachvollziehbare Fehler - da kommt keine .Net Exception mehr dir 
dir fast direkt sagt was das Problem ist - damit ist es vorbei - zu 100%

Tip:
1. schreib deinen vollständigen Ablauf in C - mit den exportierten 
Funktionen und nutzen diese Funktionen in deinem nativen Testprogramm 
bis alles 100% funktioniert - davor nicht mal im Traum an einen wechsel 
zu .Net nachdenken

du kannst dein Programm als DLL(DllMain...) oder als EXE(main) 
kompilieren - einfach als EXE kompilieren und deinen Funktionen die du 
exportieren willst sauber testen

2. beim Import die Calling-Convention beachten

3. darauf achten das in C# ein Speicherbereich nicht zwangsweise an der 
Stelle bleibt (in C muss das aber so sein) d.h. vielleicht den 
Gargbage-Collector Anweisen einen Speicher nicht zu verschieben - 
Pinning/fixed

von user (Gast)


Lesenswert?

Zu Punkt 1:

Ich habe bereits ein funktionierendes Programm. Da sehe ich keine Fehler 
oder Warnungen.

von user (Gast)


Lesenswert?

Ich konnte eine Stelle lokalisieren wo es kracht.
1
memcpy(tTelegram.u8MacAddress, u8MacAddress, 6);

von user (Gast)


Lesenswert?

Ich habe nun das eigentliche Problem gefunden.

Ein Übergabeparameter uint8_t address[6] wurde nur eine 0 übergeben.
Nun habe ich ein Dummy Array erzeugt und dieses der Funktion übergeben.

von Bert3 (Gast)


Lesenswert?

>Ich habe bereits ein funktionierendes Programm. Da sehe ich keine Fehler
>oder Warnungen.

bei nativ bedeutet das eben nicht das alles in Ordnung ist

>memcpy(tTelegram.u8MacAddress, u8MacAddress, 6);

solltes du lieber so schreiben

memcpy(tTelegram.u8MacAddress, u8MacAddress, sizeof(u8MacAddress));

von Peter II (Gast)


Lesenswert?

warum versendest du nicht direkt über C#?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.