How to get the value of a CPointer in Visual Works - smalltalk

The following C function populate a C struct in Visual Works (is working ok):
<C:int ssh_pki_import_pubkey_file (const char * filename, VOID * pkey)>
Now a second function is defined as:
int ssh_userauth_try_publickey (ssh_session session, const char * username, const ssh_key pubkey)
In Smalltalk:
<C:int ssh_userauth_try_publickey (VOID session, const char * username, const VOID pubkey)>
If i call the second function (ssh_userauth_try_publickey) with the populated argument (with no transformation) of the first function (ssh_pki_import_pubkey_file) it fail.
So VOID * pkey has to match const VOID pubkey.
In GemStone/S this is done with #'&ptr' and #'ptr', so #'&ptr' will get the value of the pointer (the CPointer’s value will be passed and updated on return).
Reading DLL & C Connect User’s Guide does not yield result yet.

Short answer
use void** in your first function and void* in your second function
Long answer
In C, void means "nothing" and if you have a return type of void that means you don't return anything.
But void* means pointer to nothing (...that i know about)... basically you get a pointer to something where you don't know what it is. But it's still a pointer, which is not nothing.
If you have a function that produces a value not via return but via parameter, you need to pass a pointer so that the function can set its value. You can do that via void* but that's unintentional. Consider the following wrong C code:
void var;
myFunc(&var);
myFunc would take a void* as parameter in order to fill its value, but a variable of type void is wrong because what would be its value. In correct C you would do it like that:
void* var = NULL;
myFunc(&var);
Here the type of var is clearly a pointer and its value is even initialised. For myFunc there's no real difference here, except that it'll now have a void** as parameter.
So if you modify ssh_pki_import_pubkey_file's declaration to have a void** parameter and change ssh_userauth_try_publickey's declaration to accept a void* parameter, you should be fine.

Related

Swift converts C's uint64_t different than it uses its own UInt64 type

I am in the process of porting an application from (Objective-)C to Swift but have to use a third-party framework written in C. There are a couple of incompatibilities like typedefs that are interpreted as Int but have to be passed to the framework's functions as UInts or the like. So to avoid constant casting operations throughout the entire Swift application I decided to transfer the C header files to Swift, having all types as I I need them to be in one place.
I was able to transfer nearly everything and have overcome a lot of hurdles, but this one:
The C header defines a struct which contains a uint64_t variable among others. This struct is used to transfer data to a callback function as a pointer. The callback function takes a void pointer as argument and I have to cast it with the UnsafeMutablePointer operation to the type of the struct (or another struct of the header if appropriate). All the casting and memory-accessing works fine as long as I use the original struct from the C header that was automatically transformed by Swift on import.
Replicating the struct manually in Swift does not "byte-fit" however.
Let me show you a reduced example of this situation:
Inside the CApiHeader.h file there is something like
typedef struct{
uint32_t var01;
uint64_t var02;
uint8_t arr[2];
}MyStruct, *MyStructPtr;
From my understanding this here should be the Swift equivalent
struct MyStruct{
var01: UInt32
var02: UInt64
arr: (UInt8, UInt8)
}
Or what should also work is this tuple notation
typealias MyStruct = (
var01: UInt32,
var02: UInt64,
arr: (UInt8, UInt8)
)
This works normally, but not as soon as there is an UInt64 type.
Okay, so what happens?
Casting the pointer to one of my own Swift MyStruct implementations the hole data is shifted by 2 bytes, starting at the UInt64 field. So in this example the both arr fields are not at the correct position, but inside the UInt64 bits, that should be 64 in number. So it seams that the UInt64 field has only 48 bits.
This accords to my observation that if I replace the UIn64 variable with this alternative
struct MyStruct{
var01: UInt32
reserved: UInt16
var02: UInt32
arr: (UInt8, UInt8)
}
or this one
struct MyStruct{
var01: UInt32
var02: (UInt32, UInt32)
arr: (UInt8, UInt8)
}
(or the equivalent tuple notation) it aligns the arr fields correctly.
But as you can easily guess var02 contains not directly usable data, because it is split over multiple address ranges. It is even worse with the first alternative, because it seams that Swift fills up the gap between the reserved field and the var02 field with 16 bits - the missing / shifted 2 bytes I mentioned above - but these are not easily accessible.
So I haven't figured out any equivalent transformation of the C struct in Swift.
What happens here exactly and how does Swift transforms the struct from the C header actually?
Do you guys have a hint or an explanation or even a solution for me, please?
Update
The C framework has an API function with this signature:
int16_t setHandlers(MessageHandlerProc messageHandler);
MessageHandlerProc is procedure type:
typedef void (*messageHandlerProc)(unsigned int id, unsigned int messageType, void *messageArgument);
So setHandlers is a C procedure inside the framework that gets a pointer to a callback function. This callback function has to provide an argument of a void Pointer, that gets casted to e.g.
typedef struct {
uint16_t revision;
uint16_t client;
uint16_t cmd;
int16_t parameter;
int32_t value;
uint64_t time;
uint8_t stats[8];
uint16_t compoundValueOld;
int16_t axis[6];
uint16_t address;
uint32_t compoundValueNew;
} DeviceState, *DeviceStatePtr;
Swift is smart enough to import the messageHandlerProc with the convention(c) syntax, so the procedure type is directly available. On the other hand it is not possible use the standard func syntax and bitcast my messageHandler callback function to this type. So I used the closure syntax to define the callback function:
let myMessageHandler : MessageHandlerProc = { (deviceID : UInt32, msgType : UInt32, var msgArgPtr : UnsafeMutablePointer<Void>) -> Void in
...
}
I converted the above mentioned structure into the different structures of my original post.
And No! Defining stats as Swift Array does not work. An Array in Swift in not equivalent to an Array in C, because Swift's Array is a extended type. Writing to and reading from it with a pointer causes an exception
Only Tuples are natively implemented in Swift and you can run back and forth with pointers over it.
Okay... this works all fine and my callback function gets called whenever data is available.
So inside myMessageHandler I want to use the stored Data inside msgArgPtr which is a void pointer and thus has to be cast into DeviceState.
let state = (UnsafeMutablePointer<MyDeviceState>(msgArgPtr)).memory
Accessing state it like:
...
print(state.time)
print(state.stats.0)
...
Whenever I use the automatically generated Swift pendant of DeviceState it all works nicely. The time variable has the Unix Time Stamp and the following stats (accessible with tuple syntax!!!) are all where they belong.
Using my manually implemented struct however results in a completely senseless time stamp value and the stats fields are shifted to the left (towards the time field - that's probably why the time stamp value is useless, because it contains bits from the stats "array"). So in the last two fields of stats I get values from compoundValueOld and the first axis field - with all the overflowing of course.
As long as I am willing to sacrifice the time value and change the UInt64 variable by either a tuple of two UInt32 types or by changing it to a UInt32 type and adding a auxiliary variable of the type UInt16 right before time, I receive a stats "array" with correct alignment.
Have a nice day! :-)
Martin
This is an update to my earlier answer after reading your updated question and experimenting some more. I believe the problem is an alignment discrepancy between the imported C structure and the one you manually implemented in Swift. The problem can be solved by using a C helper function to get an instance of the C struct from void pointer as was suggested yesterday, which can then be converted to the manually implemented Swift struct.
I've been able to reproduce the problem after creating an abbreviated mock-up of your DeviceState structure that looks like
typedef struct
{
uint16_t revision;
uint16_t client;
uint16_t cmd;
int16_t parameter;
int32_t value;
uint64_t time;
uint8_t stats[8];
uint16_t compoundValueOld;
} APIStruct;
The corresponding hand-crafted Swift native structure is:
struct MyStruct
{
init( _apis : APIStruct)
{
revision = _apis.revision
client = _apis.client
cmd = _apis.cmd
parameter = _apis.parameter
value = _apis.value
time = _apis.time
stats = _apis.stats
compoundValueOld = _apis.compoundValueOld
}
var revision : UInt16
var client : UInt16
var cmd : UInt16
var parameter : Int16
var value : Int32
var time : UInt64
var stats : (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8);
var compoundValueOld : UInt16
}
The C framework you are working with could have been compiled using a different struct packing, resulting in a non-matching alignment. I used
#pragma pack(2)
in my C code to break the bit-matching between the Swift's native and imported C struct.
If I do something like
func swiftCallBackVoid( p: UnsafeMutablePointer<Void> )
{
...
let _locMS:MyStruct = (UnsafeMutablePointer<MyStruct>(p)).memory
...
}
the data in _locMS is different from what was placed there by C code. This problem only occurs if I change struct packing using a pragma in my C code; the above unsafe conversion works fine if the default alignment is used. One can solve this problem as follows:
let _locMS:MyStruct = MyStruct(_apis: (UnsafeMutablePointer<APIStruct>(p)).memory)
BTW, the way Swift imports the C struct, the array members become tuples; this can be seen from the fact that tuple notation has to be used to access them in Swift.
I have a sample Xcode project illustrating all this that I've placed on github:
https://github.com/omniprog/xcode-samples
Obviously, the approach of using a helper C function to get APIStruct from a void pointer and then converting the APIStruct to MyStruct may or may not be an option, depending on how the structures are used, how large they are, and on the performance requirements of the application. As you can tell, this approach involves some copying of the structure. Other approaches, I think, include writing a C-layer between Swift code and the 3rd party C framework, studying the memory layout of the C structure and accessing it in creative ways (may break easily), using the imported C struct more extensively in your Swift code, etc...
Here is a way to share data between C and Swift code without unnecessary copying and with changes made in Swift visible to C code. With the following approach, however, it's imperative to be aware of object lifetime and other memory management issues. One can create a class as follows:
// This typealias isn't really necessary, just a convenience
typealias APIStructPtr = UnsafeMutablePointer<APIStruct>
struct MyStructUnsafe
{
init( _p : APIStructPtr )
{
pAPIStruct = _p
}
var time: UInt64 {
get {
return pAPIStruct.memory.time
}
set( newVal ) {
pAPIStruct.memory.time = newVal
}
}
var pAPIStruct: APIStructPtr
}
Then we can use this structure as follows:
func swiftCallBackVoid( p: UnsafeMutablePointer<Void> )
{
...
var _myUnsafe : MyStructUnsafe = MyStructUnsafe(_p: APIStructPtr(p))
...
_myUnsafe.time = 9876543210 // this change is visible in C code!
...
}
Your two definitions are not equivalent. An array is not the same as a tuple. Your C struct gives 24 bytes (see this question as to why). The size in Swift differs depend on how you implement it:
struct MyStruct1 {
var var01: UInt32
var var02: UInt64
var arr: (UInt8, UInt8)
}
typealias MyStruct2 = (
var01: UInt32,
var02: UInt64,
arr: (UInt8, UInt8)
)
struct MyStruct3 {
var var01: UInt32
var var02: UInt64
var arr: [UInt8] = [0,0]
}
print(sizeof(MyStruct1)) // 18
print(sizeof(MyStruct2)) // 18
print(sizeof(MyStruct3)) // 24, match C's

Passing function as a parameter

I want to search an array of NSDate, so here what I do:
searchResult = CFArrayBSearchValues((CFArrayRef)someDateArray, arrayRange, dateToFind, CFDateCompare, nil);
However, I get this warning:
Incompatible pointer types passing 'CFComparisonResult (CFDateRef, CFDateRef, void )' to parameter of type 'CFComparatorFunction' (aka 'CFComparisonResult ()(const void *, const void *, void *)')
How do I properly pass a function as a parameter? I think I got my syntax wrong.
You need to cast the function pointer to the CFComparatorFunction type, since it has a more explicit signature (it uses CFDateRef instead of void *).
searchResult = CFArrayBSearchValues((CFArrayRef)someDateArray, arrayRange, dateToFind, (CFComparatorFunction)CFDateCompare, nil);

What kind of pointer returned if I use "&" to get address of a value type in C++\CLI?

Suppose I write the following code:
public ref class Data
{
public:
Data()
{
}
Int32 Age;
Int32 year;
};
public void Test()
{
int age = 30;
Int32 year = 2010;
int* pAge = &age;
int* pYear = &year;
Data^ data = gcnew Data();
int* pDataYear = &data->Year; // pData is interior pointer and the compiler will throw error
}
If you compile the program, the compiler will throw error:
error C2440: 'initializing' : cannot convert from 'cli::interior_ptr' to 'int *'
So I learned the "&data->Year" is a type of interior pointer.
UPDATES: I tried to use "&(data->Year)", same error.
But how about pAge and pYear?
Are they native pointers, interior pointers or pinned pointers??
If I want to use them in the following native function:
void ChangeNumber(int* pNum);
Will it be safe to pass either pAge or pYear?
They (pAge and pYear) are native pointers, and passing them to a native function is safe. Stack variables (locals with automatic storage lifetime) are not subject to being rearranged by the garbage collector, so pinning is not necessary.
Copying managed data to the stack, then passing it to native functions, solves the gc-moving-managed-data-around problem in many cases (of course, don't use it in conjunction with callbacks that expect the original variable to be updated before your wrapper has a chance to copy the value back).
To get a native pointer to managed data, you have to use a pinning pointer. This can be slower than the method of copying the value to the stack, so use it for large values or when you really need the function to operate directly on the same variable (e.g. the variable is used in callbacks or multi-threading).
Something like:
pin_ptr<int> p = &mgd_obj.field;
See also the MSDN documentation

Pass an argument by reference in C++/CLI so re-assignment affects the caller

Probably this is not a difficult question, but I am always a little bit confused on how to treat String type as an argument in Visual C++. I have the following to functions:
void function_1(String ^str_1)
{
str_1 = gcnew String("Test");
}
void function_2()
{
String ^str_2 = nullptr;
function_1(str_2);
}
After calling function_1, str_2 is still equal to null, but what I want to achieve is that str_2 is equal to Test. So, how can I achieve that the content of str_1 is passed to function_2?
Thanks for any advice.
Use a tracking reference:
void function_1(String ^%str_1)
{
str_1 = gcnew String("Test");
}
Explanation: Passing String ^ is like passing a pointer. Changes are only made to the local copy of the reference. String ^% is like passing a reference to a reference... just as you would pass a pointer to a pointer when calling a function that should change the original pointer.

Difference between value parameter and reference parameter?

Difference between value parameter and reference parameter ? This question is asked sometime by interviewers during my interviews. Can someone tell me the exact difference that is easy to explain with example? And is reference parameter and pointer parameter are same thing ?
Thanks
Changes to a value parameter are not visible to the caller (also called "pass by value").
Changes to a reference parameter are visible to the caller ("pass by reference").
C++ example:
void by_value(int n) { n = 42; }
void by_ref(int& n) { n = 42; }
void also_value(int const& n); // Even though a reference is used, this is
// semantically a value parameter---though there are implementation
// artifacts, like not being able to write "n = 42" (it's const) and object
// identity (&n here has different ramifications than for by_value above).
One use of pointers is to implement "reference" parameters without using a special reference concept, which some languages, such as C, don't have. (Of course you can also treat pointers as values themselves.)
The main difference is whether the object passed is copied. If it's a value parameter the compiler must generate such code that altering the function parameter inside the function has no effect on the original object passsed, so it will usually copy the object. In case of reference parameters the compiler must generate such code taht all operations are done on the original object being passed.
A pointer is a low-level way of representing a reference, so passing a pointer (by value) is how languages like C typically achieve pass by reference semantics.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or by copy.
There are basically three kinds of parameters; pointer, reference and direct.
The difference is pretty simple: direct parameters are passed by value, and the receiver receives a copy of what is passed; meaning that if the parameter is modified by the receiver, these changes will not be reflected back to the caller. (This is often called, appropriately enough, pass by value, or bycopy.
Pointers are also passed by value, but rather than sending the actual value, the caller sends the address of the value. This means that by following this pointer, the receiver can modify the argument. Note that changes made to the actual pointer still aren't reflected back to the caller.
The final form, call-by-reference, is sort of a middle ground between these two approaches. Essentially it can be thought of as a pointer that looks like a value.
It is worth mentioning that at the core of it all, parameters are always passed by value, but different languages have different ways of implementing reference semantics (see Kylotans answer).
// Example using C
// bycopy
int multiply(int x, int y) {
return x * y;
}
void multiply_p(int *x, int y) {
*x *= y;
}
int main () {
int i, j, k;
i = 20;
j = 10;
k = multiply(i,j); // k is now 200
multiply_p(&i, k); // i is now 4000 (200 * 20)
return 0;
}
Pseudocode:
Pass by Value:
void setTo4(value) { // value is passed by value
value = 4;
}
int x = 1;
setTo4(x);
// x is still 1
Pass by Reference:
void setTo4(value) { // value is passed by reference
value = 4;
}
int x = 1;
setTo4(x);
// x is 4