TurboMagic 92 Posted June 30, 2021 I'm writing a DLL which shall be called by LabView (among other environments). Calling a simple function which gets 2 numbers, adds them and returns the result works. That one uses calling convention cdecl, as specified by the "client". But strings are a problem. For getting this tested I developed the following simple function, which shall be called by a LabView test application but this always crashes inside the DLL. Currently it crashes here: "Exception beim Stringrückliefern", if I make a var parameter out of CalcRes it immediately crashes here: "Exception in Berechnung". What might cause this? The caller shall pass a string which a number of chars allocated for and the number of chars he allocated the string for + the #0 terminator in CalcResSize. If the result fits in that, it is returned in the string. CalcResSize will represent the number of bytes needed for the string including the #0 after the call so if the caller didn't pass a long enough string he can call the function again using a longer string. Here's the code: uses System.SysUtils, System.AnsiStrings; function Add(Number1, Number2: UInt8; CalcRes: PAnsiChar; var CalcResSize: UInt8): UInt16; cdecl; var Res : UInt16; ResStr : AnsiString; begin try Res := Number1 + Number2; ResStr := AnsiString(Res.ToString); except On E:Exception do begin OutputDebugString(PWideChar('Exception in Berechnung: ' + E.Message)); Result := 2; Exit; end; end; try if Assigned(CalcRes) and ((Length(ResStr) {* SizeOf(Char)} + 1) <= CalcResSize) then begin System.AnsiStrings.StrPLCopy(CalcRes, ResStr, CalcResSize); Result := 0; end else Result := 1; except On E:Exception do begin OutputDebugString(PWideChar('Exception beim Stringrückliefern: ' + E.Message + ' / ' + madExcept.GetCrashStackTrace)); Result := 2; Exit; end; end; try CalcResSize := (Length(ResStr) {* SizeOf(Char)} + 1); except On E:Exception do begin OutputDebugString(PWideChar('Exception in CalcResSize Berechnung: ' + E.Message + ' / ' + madExcept.GetCrashStackTrace)); Result := 2; Exit; end; end; end; Cheers TurboMagic Share this post Link to post
Guest Posted June 30, 2021 48 minutes ago, TurboMagic said: System.AnsiStrings.StrPLCopy(CalcRes, ResStr, CalcResSize); This is problem maker. 1) I would stay away from any string RTL string functions when it comes to passing raw data to/from different built DLL, use simple Move. 2) You already are checking Length against CalcResSize but you are using CalcResSize!! you should copy only your string length as CalcResSize might be 10kb while your string is 3 bytes, can you see the problem now ? 3) In any case, E.Message and the Stack will be way more helpful to understand the bug, is it access violation ? and on what address ? Share this post Link to post
TurboMagic 92 Posted July 1, 2021 Thanks for the answer. I changed it to use Move now like this: Move(ResStr[1], CalcRes[0], Length(ResStr)); In my Delphi test application it works flawlessly, but the LabView application calling the DLL still crashes it. Access violation at address 184E140E ... Read of address 00000003 I will try to log the address of the PChar passed in now and if possible it's contents at that time, but I don't know how to read raw RAM for getting a bit more loginfo... Share this post Link to post
Virgo 18 Posted July 1, 2021 (edited) What happens, when this Add is called with nil as CalcRes? Typically in C style API's function then assigns required string length without copying string. So that caller would know, how much memory to allocate. Never mind. I did not read correctly original code, this is already handled. But what are requirements on function result? Also possible issues with ending #0 - is it required in CalcRes? Edited July 1, 2021 by Virgo Share this post Link to post
Fr0sT.Brutal 900 Posted July 1, 2021 BTW, you can debug DLLs by defining host process in Run options dialog. Then you can set breakpoints and see what's going on in fact. Share this post Link to post
David Heffernan 2345 Posted July 1, 2021 (edited) 15 hours ago, Kas Ob. said: This is problem maker. Nah, that's not going be to the cause of the error reported in the original post. Hard to say what is the problem though without knowing the other side of the interface. How can we know how the function is declared in labview? My expectation is that the real issue is a mismatch at the binary interface layer. Edited July 1, 2021 by David Heffernan Share this post Link to post
Guest Posted July 1, 2021 29 minutes ago, David Heffernan said: Nah, that's not going be to the cause of the error reported in the original post. The line in full is what i meant, not StrPLCopy specifically, between the unchecked size (which is seem not the problem now) and the pointer type. And you are right there, it is about the other side, is it simple pointer or something else ? Share this post Link to post
Fr0sT.Brutal 900 Posted July 1, 2021 According to https://m.eet.com/media/1089230/an087.pdf , function must be stdcall Share this post Link to post
TurboMagic 92 Posted July 1, 2021 It works now, last failure was to not declare the last function parameter as pointer in the header file they use as this is a var param on my side. Share this post Link to post