-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to correctly describe a pointer and a pointer to a pointer? #92
Comments
Please format your text with markdown syntax, i can't read it friendly. If you want to create a pointer point to i32, just use |
Sorry. I corrected the formatting and tried to describe it in more detail |
You can refer to other issues to realize how to call win API by ffi-rs |
I advise you to figure out the parameters meaning of c.
|
Without unwarp: Uncaught Error Error: expect External, got: Object |
createPointer will return an array of pointer, you should use index 0 to get the pointer element. You can write it with typescript for type hints |
Yes, it compiles but doesn't work as expected:
Output: 0 {} |
Use restorePointer to restore the value in the pointer |
Final for LPDWORD. It works! Thank you.
Output: 100 Question about this code: Should I free the pointer? Or should I clear the pointer only if in createPointer paramsType = DataType.External?
Often in WinAPI we use NULL (nullptr) in parameters instead of a data pointer to indicate to WinAPI that we are not using this parameter. What is the best way to create NULL (nullptr)?
|
Use Use the code below to create null pointer
|
The most significant problem. I have greatly simplified the example and left only the essence of the problem. C++ // WinApi32.dll
// Allocate 100 chars (bytes) buffer and fill 99 chars with 'A', return POINTER to allocated buffer
void MemAlloc(char** ppBuffer)
{
*ppBuffer= (char*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, 100); // Allocate 100 (bytes) buffer and save pointer
memset ((void*)*ppBuffer, 65 /* 'A' */, 99 ); // fill 99 chars with 'A'
}
// Free allocated buffer
void MemFree(char* pBuffer)
{
::HeapFree(::GetProcessHeap(), 0x00, pBuffer);
}
// C++ Usage
int main(void)
{
char* pBuffer = nullptr;
MemAlloc(&pBuffer);
printf("%s", pBuffer); // -> AAAAAAAAAAAAAAAAAAAAAAAAAAA....
MemFree(pBuffer);
return 0;
} JS I don't know how to correctly describe import. const winapi = define({
MemAlloc: {
library: WinApi32dll,
retType: DataType.Void,
paramsType: [ DataType.External]
},
MemFree: {
library: WinApi32dll,
retType: DataType.Void,
paramsType: [ DataType.External ]
}
})
winapi.MemAlloc(????);
winapi.MemFree(????); Sorry for my persistence but totally stuck at this point in code. |
You can find the same type definition in test cases and call examples
|
I looked at the code provided and did not find a solution. In your examples there is a size of the returned data, you create arrays based on this size or get ** in retType of DataType.External.
|
you can't restore an array without specify length safety,or you can restore it with a big size
发自我的iPhone
…------------------ Original ------------------
From: Ytd ***@***.***>
Date: Wed,Jan 22,2025 8:46 PM
To: zhangyuang/node-ffi-rs ***@***.***>
Cc: yuuang ***@***.***>, Comment ***@***.***>
Subject: Re: [zhangyuang/node-ffi-rs] How to correctly describe a pointer anda pointer to a pointer? (Issue #92)
You can find the same type definition in test cases and call examples
char** is a string array type
I looked at the code provided and did not find a solution.
In your examples there is a size of the returned data, you create arrays based on this size or get ** in retType of DataType.External.
In my case, the library returns a pointer to a buffer in a variable that I specified, in which I can find data, the size is not known to me and is not needed, since it will simply return a zero-terminated buffer to me.
char* pBuffer = nullptr; MemAlloc(&pBuffer); printf("%s", pBuffer); // -> AAAAAAAAAAAAAAAAAAAAAAAAAAA.... MemFree(pBuffer);`
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
Let's do it differently, without text (char) data. The buffer will be a void type: void* pBuffer = nullptr; I want to get a pointer to it (it is allocated in C++) MemAlloc(&pBuffer); and I want to move through it until I find the first zero, outputting all the data to the console. At the end, I'll call flushing this buffer using C++. MemFree(pBuffer); How to get a direct pointer to allocated C++ memory on the heap? const voidPtr = createPointer({ paramsType: [DataType.RefVoid], paramsValue: [ 0 /* init value */ ] }); // <-- C++ void* pBuffer = nullptr;
let pVoid = unwrapPointer(voidPtr)[0]; // &pBuffer
winapi.MemAlloc(pVoid); // C++ MemAlloc(&pBuffer);
let text = Buffer.from(refPointer(voidPtr)[0], 0, 100 /* 100 for simplicity */) /* function not found in ffi-rs*/);
console.log(text.toString());
winapi.MemFree(pVoid); // C++ MemFree(pBuffer); |
create DataType.u8array pointer with an enough size and fill it in c environment
发自我的iPhone
…------------------ Original ------------------
From: Ytd ***@***.***>
Date: Wed,Jan 22,2025 9:14 PM
To: zhangyuang/node-ffi-rs ***@***.***>
Cc: yuuang ***@***.***>, Comment ***@***.***>
Subject: Re: [zhangyuang/node-ffi-rs] How to correctly describe a pointer anda pointer to a pointer? (Issue #92)
you can't restore an array without specify length safety,or you can restore it with a big size
发自我的iPhone
…
Let's do it differently, without text (char) data.
The buffer will be a void type:
void* pBuffer = nullptr;
I want to get a pointer to it (it is allocated in C++)
MemAlloc(&pBuffer);
and I want to move through it until I find the first zero, outputting all the data to the console.
At the end, I'll call flushing this buffer using C++.
MemFree(pBuffer);
How to get a direct pointer to allocated C++ memory on the heap?
const voidPtr = createPointer({ paramsType: [DataType.RefVoid], paramsValue: [ 0 /* init value */ ] }); // <-- C++ void* pBuffer = nullptr; let pVoid = unwrapPointer(voidPtr)[0]; // &pBuffer winapi.MemAlloc(pVoid); // C++ MemAlloc(&pBuffer); let text = Buffer.from('ucs2', refPointer(voidPtr)[0] /* function not found in ffi-rs*/); console.log(text.toString()); winapi.MemFree(pVoid); // C++ MemFree(pBuffer);
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you commented.Message ID: ***@***.***>
|
Do I understand correctly that your library cannot work with pointer to pointer as argument to functions in C++ ? func2(int **x); Example: void func1(int *);
void func2(int **);
int i = 100;
int *ptr = &i;
// when you want value of ptr should remain unchanged, but you want to change only value of i, use,
func1(int *)
// when you want value of ptr should change. i.e, it should point to some other memory other than i, use,
func2(int **); |
Use |
Finally. My fully working version. In C++ everything works correctly. const voidPtr = createPointer({ paramsType: [DataType.Void], paramsValue: [ null ] }); // void* pBuffer = nullptr;
const stringPtr = wrapPointer(voidPtr)[0]; // &pBuffer
winapi.MemAlloc(stringPtr); // MemAlloc(&pBuffer)
console.log(restorePointer( { retType: [DataType.WString] , paramsValue: [ stringPtr ] } ), // printf('%s', (wchar*)pBuffer);
winapi.MemFree(stringPtr ); // MemFree(pBuffer);
freePointer({ paramsType: [DataType.Void], paramsValue: voidPtr, pointerType: PointerType.RsPointer } ); |
The process crashes when I use freePointer. What is my mistake? // Process exited with code 3221226505 let ctxData = new Buffer.alloc(16).fill(0);
const ctxPtr = createPointer({ paramsType: [DataType.U8Array], paramsValue: [ ctxData] });
freePointer({ paramsType: [DataType.U8Array], paramsValue: ctxPtr, pointerType: PointerType.RsPointer } ); |
|
Thank you, your code works, but I don’t understand what’s wrong with my version? |
Use arrayConstructor to create array type instead of DataType.array |
I guess this is my last question. You're probably already tired of me.
My attempts are in JS but I don't understand if my approach is correct // ffi-rs type
const winapi = sqlconnectioninfoType : {
cbSize: DataType.I32,
szServerName : arrayConstructor({ type: DataType.U8Array, length: 261*2, ffiTypeTag: DataType.StackArray }),
szDataBaseName: arrayConstructor({ type: DataType.U8Array, length: 129*2, ffiTypeTag: DataType.StackArray }),
bIntegratedAuthentication : DataType.I32,
szLogin : arrayConstructor({ type: DataType.U8Array, length: 129*2, ffiTypeTag: DataType.StackArray }),
szPassword : arrayConstructor({ type: DataType.U8Array, length: 129*2, ffiTypeTag: DataType.StackArray })
}
// JS user data
const sqlconnectinfo = {
server: '(local)',
database: 'model',
intauth: false,
login : 'sqluser',
password: 'sqlpass'
};
// ffi-rs pointer
const _sqlconnectinfo_ptr = createPointer({ paramsType: [ winapi.sqlconnectioninfoType ], paramsValue: [ {
cbSize: winapi.sqlconnectioninfoSize.v1, /* i know size */
szServerName: Buffer.from(sqlconnectinfo.server + '\0', 'ucs2'),
szDataBaseName: Buffer.from(sqlconnectinfo.database + '\0', 'ucs2'),
bIntegratedAuthentication: sqlconnectinfo.intauth ? 1 : 0,
szLogin: Buffer.from(sqlconnectinfo.login + '\0', 'ucs2'),
szPassword: Buffer.from(sqlconnectinfo.password + '\0', 'ucs2')
}] });
// raw pointer
const _pSqlconnectinfo = unwrapPointer(_sqlconnectinfo_ptr)[0];
// Call
winapi.lib.SqlConnect(_pSqlconnectinfo );
freePointer({ paramsType: [winapi.sqlconnectioninfoType], paramsValue: _sqlconnectinfo_ptr, pointerType: PointerType.RsPointer }); |
Support DataType.I16Array in [email protected] Use i16Array to represent
|
If there is a way to initialize an array with default value? |
|
Current ffi-rs version
Current Node.js arch
Descibe your problem in detail
I read the description of the library but could not call some WinAPI functions. Perhaps I didn't understand correctly how to use the library. I would really like you to explain it to me.
There are a couple of functions:
Pseudo example of Windows x32-x86 dll module:
How to call such functions correctly? I don't understand how to describe the parameters for
My implementation in Node
To describe the GUID in NODE I used this monster construction.
It works. Next, I convert it from binary to text form and everything is ok. Did I choose the right way or not?
For a pointer to a DWORD I can use a pointer to an Int32, but it doesn't work!
What would be the correct way to send NULL in WinAPI?
I can’t understand how to describe pointer to pointer
LPWSTR* -> char** - the most important parameter for both functions
The text was updated successfully, but these errors were encountered: