Buffer and pointers in Delphi from C DLL - function

I am still learning from the DLL process and since no Delphi FTDI Libmpsse library exist, I must work my own way through with the DLL from scratch.
However, I'm far from perfect in Delphi!
I've been using it for few years without touching pointers.
This is the particular line I'm now stuck with (This is what I've tried to translate):
function I2C_DeviceWrite(
handle :dword;
deviceAddress :uint32;
sizeToTransfer :uint32;
out buffer :byte;
out sizeTransferred :uint32;
options :uint32
):FT_Result; cdecl; external 'libmpsse.dll';
From the API User guide it is describe the C way like this:
FT_STATUS I2C_DeviceWrite(
FT_HANDLE handle,
uint32 deviceAddress,
uint32 sizeToTransfer,
uint8 *buffer,
uint32 *sizeTransferred,
uint32 options )
Asterix means pointer in C from what I understand.
I don't know how to declare them properly yet.
Any hints?
NB: I'm still reading (XE2 Foundations) and searching about pointers and buffers the most I can!
Thank you!
BTW, API Guide is here for consulation:PDF from FTDI
EDIT:
var
Buffer: array of Byte;
written,towrite:cardinal;
begin
SetLength(Buffer,I2C_DEVICE_BUFFER_SIZE);
buffer[0] := $07;
towrite := 1;
i2c_openchannel(1,FT_HANDLE); //open channel 1
i2c_initchannel(FT_HANDLE,I2C_CLOCK_STANDARD_MODE and LATENCY_TIMER and 0);
i2c_devicewrite(FT_HANDLE,I2C_DEVICE_ADDRESS,towrite,buffer,written,I2C_TRANSFER_OPTIONS_START_BIT);
i2c_closechannel(FT_HANDLE); //close device
So far so good everything else work except the i2c_devicewrite line!It gives me E2033:unable to compile actual and formal var parameters must be identical

You've translated the byte array parameter incorrectly. You used
out buffer: byte
which is a single byte, passed out by reference. It should be
buffer: PByte
which here means a pointer to array of byte.
Then pass the address of the first element of the array. Like this:
#Buffer[0]
or like this
PByte(Buffer)
Note that I've not checked anything other than the byte array parameter.
FWIW, a constant length array may be simpler here than a dynamic array.
I'd also comment that you appear to be ignoring return values. Never do that. Always check return values for errors.

Related

how to make Ghidra use a function's complete/original stackframe for decompiled code

I have a case where some function allocates/uses a 404 bytes temporary structure on the stack for its internal calculations (the function is self-contained and shuffles data around within that data structure). Conceptually the respective structure seems to consist of some 32-bit counters followed by an int[15] and a byte[80] array, and then an area that might or might not actually be used. Some of the generated data in the tables seems to represent offsets that are again used by the function to navigate within the temporary structure.
Unfortunately Ghidra's decompiler makes a total mess while trying to make sense of the function: In particular it creates separate "local_.." int-vars (and then uses a pointer to that var) for what should correctly be a pointer into the function's original data-structure (e.g. pointing into one of the arrays).
undefined4 local_17f;
...
dest= &local_17f;
for (i = 0xf; i != 0; i = i + -1) {
*dest = 0;
dest = dest + 1;
}
Ghidra does not seem to understand that an array based data access is actually being used at that point. Ghirda's decompiler then also generates a local auStack316[316] variable which unfortunately seems to cover only a part of the respective local data structure used by the original ASM code (at least Ghidra actually did notice that a temporary memory buffer is used). As a result the decompiled code basically uses two overlapping (and broken) shadow data structures that should correctly just be the same block of memory.
Is there some way to make Ghidra's decompiler use the complete 404 bytes block allocated by the function as an auStack404 thus bypassing Ghidra's flawed interpretation logic and actually preserve the original functionality of the ASM code?
I think I found something.. In the "Listing" view the used local-variable layout is shown as a comment under the function's header. It seems that by right clicking on a respective local-var line in that comment, "set data type" can be applied to a respective local variable. Ah, and then there is what I've been looking for under "Function/"Edit stack frame" :-)

Returning a pointer on stack

In C when I return a pointer of a stack-created variable from a function, the memory discards after the function is returned, thus making the pointer impossible to dereference. But in Go, the compiler is not giving me any errors. Does that mean that this is safe to do?
package main
import (
"fmt"
)
func main() {
fmt.Println(*(something()))
}
func something() *string {
s := "a"
return &s
}
Yes, this is safe and a normal pattern in Go programming. Go uses escape analysis to move any values with pointers that escape the stack to the heap automatically. You don't need to be concerned with where values are allocated.
From the Go FAQ: "How do I know whether a variable is allocated on the heap or the stack?"
if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors
You can see these optimization choices during compilation by using the -gcflags -m option.
Yes, in Golang it is fine to return a pointer to a local variable. Golang will manage the objects lifetime for you and free it when all pointers to it are gone.
In another answer I point out all the differences between C/C++ pointers and Golang pointers: What is the meaning of '*' and '&' in Golang?

In Ethereum Solidity, when changing an array length, I get "Value must be an lvalue". Why?

In Solidity, you can increase the size of an array to make room for a new member by using array.length++. But I'm getting an error:
Value must be an lvalue
You can resize a dynamic array in storage (i.e. an array declared at the contract level) with “arrayname.length = ;” But if you get the “lvalue” error, you are probably doing one of two things wrong.
You might be trying to resize an array in memory, or
You might be trying to resize a non-dynamic array.
int8[] memory somearray; // CASE 1
somearray.length++; // illegal
int8[5] somearray; // CASE 2
somearray.length++; // illegal
IMPORTANT NOTE: In Solidity, arrays are declared backwards from the way you’re probably used to declaring them. And if you have a >=2D array with some dynamic and some non-dynamic components, you may violate #2 and not understand why. Note also that arrays are accessed the “normal” way. Here's are some examples of this "backward" declaration paradigm in action:
int8[][5] somearray; // This is 5 dyn arrays, NOT a dyn array-of-arrays w/len=5
// so...
somearray[4]; // the last dynamic array
somearray[1][12]; // the 13th element of the second dynamic array
// thus...
somearray.length++; // illegal. This array has length 5. Always.
somearray[0].length++;// legal
Encountered same issue and what I had to was use the storage keyword since I was trying to modify a global storage array.
bytes32[] storage someArray = someGlobalStorageArray;

How can I iterate Dynamic object in Haxe

I have Object parsed from JSON (haxe.Json.parse()) and I need to iterate over it.
I already tried to cast this object to Array<Dynamic>:
var data:String='{"data":{"0":0,"1":1},"method":"test"}';
var res:{method:String,data:Array<Dynamic>} = haxe.Json.parse(data);
for (n in res.data)
trace('aa')
There is no Can't iterate dynamic exception, just not working (iterating).
I completley don't understand why in Haxe iterating procedure is so difficult.
For the sake of posting a complete answer, and in case other people are wondering
In your first example, you've told the compiler that "res" contains two properties - one called "method" (which is a String) and one called "data" (which is Array). Now the JSON you're using doesn't actually have an Array<Dynamic>, it just has a dynamic object. An Array would look like: "data":[0,1].
So, assuming you meant for the JSON to have data as a Dynamic object, here is how you loop over it, using Reflect (as you mentioned in the comments):
var data:String='{"data":{"0":0,"1":1},"method":"test"}';
var res = haxe.Json.parse(data);
for (n in Reflect.fields(res.data))
trace(Reflect.field(res.data, n));
Note here we don't have to specify the type of "res", since we're using Reflection just leaving it as Dynamic will be fine.
Now, if your JSON actually contains an Array, the code might look like this:
var data:String='{"data":[0,1],"method":"test"}';
var res:{method:String,data:Array<Int>} = haxe.Json.parse(data);
for (n in res.data)
trace(n);
Here you use explicit typing to tell the compiler that res.data is an Array (and this time it actually is), and it can loop over it normally.
The reason you didn't get an error at compile-time is because the compiler thought there was genuinely going to be an array there, as you told it there was. At runtime, whether or not it throws an exception probably depends on the target... but you probably want to stay out of that anyway :)
Demo of both styles of code: http://try.haxe.org/#772A2

Function pointer to specific memory

I'd like to ask for an advice. I am working with small embedded uP.
I'd like to assign my various functions to myfunctions struct. How to do that correctly?
Then I want to place this myfunctions (struct of function pointers) to specific memory address (e.g. 0x1000). Whats is the best procedure to achieve this?
typedef void (*fptr)(void);
typedef struct FCN_IMAGE
{
fptr fcn1;
fptr fcn2;
fptr fcn3;
} FUNC_T;
FUNC_T myfunctions;
Actually it should be sort of jump table.
Secondly I want to read this function pointers from within other program - directly from specified address location (e.g. 0x1000).
It means the first code should assign the struct of function pointers to specific memory location and other independent code should read this table from specific memory. Interconnection between those two programs should be
#define FCN_BASE_ADDRESS (0x1000)
Any ideas what is the best way to achieve it?
P.S. This will run on embedded processor - not PC.
Locating objects at specific locations is usually most easily performed by the use of compiler specific extension; there is no standard method defined by the language. It may also be possible to locate a global object at a specific location by modifying the linker script, but that will be specific to your particular tool-chain
What compiler/tool-chain are you using? Refer to its documentation.
Maybe the following will help you:
// assign my various functions to myfunctions struct
myfunctions.fcn1 = &YourFunction1;
myfunctions.fcn2 = &YourFunction2;
myfunctions.fcn3 = &YourFunction3;
// assign the struct of function pointers to specific memory location
memcpy((void*)FCN_BASE_ADDRESS, &myfunctions, sizeof(myfunctions));
// read this table from specific memory
memcpy(&myfunctions, (void*)FCN_BASE_ADDRESS, sizeof(myfunctions));
This is based on my guess on what you actually want to do.
This is the best way to solve it in a portable manner:
typedef void (*fptr)(void);
#define FCN_BASE_ADDRESS ((volatile fptr*)0x1000)
/* Make myfunctions an array, not a struct.
Structs can have padding and aren't portable.
It doesn't look like you need a struct in this case.
*/
fptr myfunctions [N] =
{
fptr fcn1;
fptr fcn2;
fptr fcn3;
};
memcpy(&FCN_BASE_ADDRESS, myfunctions, sizeof(myfunctions));
Though if you are using Codewarrior, you could probably use a #pragma to allocate them where you want them. Here is an example assuming they are stored in read/write RAM and a 32-bit address bus.
// .prm file
SECTIONS
MEM_FCN_BASE_ADDRESS = READ_WRITE 0x2000 TO 0x200C;
END
PLACEMENT
FCN_BASE_ADDRESS INTO MEM_FCN_BASE_ADDRESS;
END
// .c file
#pragma DATA_SEG FCN_BASE_ADDRESS
fptr myfunctions[N] = ...;
#pragma DATA_SEG DEFAULT
If they should be stored in ROM/flash, for example a vector table, then it must be done differently with READ_ONLY sections, #pragma CONST_SEG and const fptr. (Note that the const keyword in C behaves in irrational ways when combined with typedef:ed pointers. In this case I believe it would give a constant pointer to a non-constant function and thus it should end up in NVM as desired.)