Hallo Christian,
bei einer Funktion die als Return Type char * hat ohne dass der Aufrufer einen Puffer und die Puffergröße übergeben muss, gehen bei mir ehrlich gesagt erst mal die Alarmglocken an. Wo kommt denn der String her? Wer muss den Speicher wieder frei geben oder ist es ein pointer auf einen statischen String?
Wenn ich das nicht beantworten kann, dann lasse ich da meine finger weg und wenn ich selbst eine DLL schreibe, dann mache ich so etwas erst gar nicht.
(Den Fall meide ich seit ewigen Zeiten wie die Pest und kann deine Frage(n) daher auch nur bedingt beantworten)
Der Aufrufer stellt den Puffer zur Verfügung und sagt, wie groß der Puffer ist. Übergibt der Aufrufer eine Puffergröße von 0 und/oder einen Null Pointer, dann liefert die Funktion entweder einen Fehler oder sie sagt, wie groß der Puffer sein sollte. Wenn es denn unbedingt sein soll, dass der DLL Funktion den Speicher allokiert, dann bitte nur Optional und nur wenn beschrieben wird, wo der Puffer her kommt. Ein Beispiel für letzteren Fall wäre z.B.
FormatMessage
LabVIEW hat seinen eigenen Speichermanager und du hast so gut wie gar keinen Einfluss darauf, wann Speicher allokiert wird und wann er von LabVIEW wieder freigegeben wird. Wenn eine Funktion also ein char * zurück liefert und du diesen als LStrHandle in Labview haben möchtest, dann muss LabVIEW in der Call Library Node den C-String auf den char * zeigt umkopieren, also zunächst einmal dessen Länge feststellen, Speicher in der passenden größe allokieren und den String umkopieren.
Das sollte IMHO auch erst einmal gut funktionieren. Ein CStr endet beim ersten 0x00 Zeichen. Ist die Zeichenkette z.B. in UTF-16 kodiert, dann kann das nicht mehr funktionieren. Es funktioniert auch dann nicht, wenn die aufrufende Funktion den benötigten Speicher dynamisch allokiert und der Aufrufer den Speicher wieder freigeben soll.
Zunächst wären also ein paar Fragen zu klären:
Wo kommt der Speicher her auf den der Pointer zeigt? Und gegebenenfalls auch: Wer und wie wird dieser Speicher wieder freigegeben?
Wie ist der String kodiert?
Weil ihr die DLL ja selbst erstellt, würde ich jetzt einfach den Entwickler der DLL freundlich aber bestimmt darauf hinweisen, dass diese Funktion keine so gute Idee ist und ihn bitten (oder auch mit einer Tasse Kaffee "bestechen") einfach zusätzlich noch folgende Funktion zu implementieren:
const int __stdcall getErrorMessageExt(int errorVal, char *Buffer, int BufferSize);
Die Funktion prüft, ob der übergebene Puffer groß genug ist für den String (und Buffer ungleich NULL ist). Falls das passt, dann wird die Fehlermeldung dort hineinkopiert.
Return Wert: Anzahl der Zeichen im String. Im Fehlerfall ist der Return Wert null.
Das sollte in ein paar Minuten inclusive Doku erledigt sein und spart auf der anderen Seite viele Stunden an Nachfragen und Überlegungen (ganz unabhängig von der Programmiersprache stellt sich das immer). Alleine die Zeit für dieses Postings dauert schon länger als das Implementieren einer solchen Funktion. Es wäre überflüssig wenn es eine solche Funktion bereits geben würde.