I'm trying to understand why in HANDLETABLE struct objectHandle is an array of handles.
As I understand, HGDIOBJ is a void pointer and therefore objectHandle is an array of void pointer with an element. But in the book Programming Windows 5th Edition, author said that the field is actually of variable length.
How can it work? I think that objectHandle only have 1 element??
Related
I was looking at Microsoft site about single inheritance. In the example given (code is copied at the end), I am not sure how memory is allocated to Name. Memory is allocated for 10 objects. But Name is a pointer member of the class. I guess I can assign constant string something like
DocLib[i]->Name = "Hello";
But we cannot change this string. In such situation, do I need allocate memory to even Name using new operator in the same for loop something like
DocLib[i]->Name = new char[50];
The code from Microsoft site is here:
// deriv_SingleInheritance4.cpp
// compile with: /W3
struct Document {
char *Name;
void PrintNameOf() {}
};
class PaperbackBook : public Document {};
int main() {
Document * DocLib[10]; // Library of ten documents.
for (int i = 0 ; i < 10 ; i++)
DocLib[i] = new Document;
}
Yes in short. Name is just a pointer to a char (or char array). The structure instantiation does not allocate space for this char (or array). You have to allocate space, and make the pointer(Name) point to that space. In the following case
DocLib[i]->Name = "Hello";
the memory (for "Hello") is allocated in the read only data section of the executable(on load) and your pointer just points to this location. Thats why its not modifiable.
Alternatively you could use string objects instead of char pointers.
I'm still learning C++, and I'm doing some API work, but I'm, having trouble parsing this pointer arrangement.
void* data;
res = npt.receive(0x1007, params, 1, response, (void**)&data, size);
uint32_t* op = (uint32_t*)data;
uint32_t num = *op;
op++;
Can anyone explain what is going on with that void pointer? I see it being defined, it does something in the res line(maybe initialized?), then it's copied to an uint32 pointer, and dereferenced in num. Can anyone help me parse the (void**)&data declaration?
Pay attention when you use the void pointer:
The void type of pointer is a special type of pointer. In C++, void represents the absence of type. Therefore, void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties).
This gives void pointers a great flexibility, by being able to point to any data type, from an integer value or a float to a string of characters. In exchange, they have a great limitation: the data pointed to by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason, any address in a void pointer needs to be transformed into some other pointer type that points to a concrete data type before being dereferenced.
From C++ reference
Firstly: What is npt?
Secondly: Guessing what npt could be some explanation:
// Declare a pointer to void named data
void* data;
// npt.receive takes as 5th parameter a pointer to pointer to void,
// which is why you provide the address of the void* using &data.
// The void ** appears to be unnecessary unless the data type of the
// param is not void **
// What is "npt"?
res = npt.receive(0x1007, params, 1, response, (void**)&data, size);
// ~.receive initialized data with contents.
// Now make the uint32_t data usable by casting void * to uint32_t*
uint32_t* op = (uint32_t*)data;
// Use the data by dereferencing it.
uint32_t num = *op;
// Pointer arithmetic: Move the pointer by sizeof(uint32_t).
// Did receive fill in an array?
op++;
Update
Signature of receive is:
<whatever return type> receive(uint16_t code, uint32_t* params, uint8_t nparam, Container& response, void** data, uint32_t& size)
So the data parameter is of type void** already so the explicit type cast to void** using (void**) is not necessary.
Considering the usage, the received data appears to be an array of uint32_t values IN THIS CASE!
Void as a type means no type and no type information regarding size and alignment is available, but is mandatory for lexical and syntactical consistency.
In conjunction with the *, it can be used as a pointer to data of unknown type and must be explicitly cast to another type (adds type information) before any use.
You usually have a void* or void** in an API, if you dont know the specific data type or only received plain byte data.
To understand this please read up C type erasure using void*
Please read up as basics before:
Dynamically allocated C arrays.
Pointers and Pointer Arithmetics.
From the code, ntp.receive tells you whether it receives anything successfully in the return code but it also needs to give you what it receives. It has a pointer that it wants to pass back, so you have to tell it where that pointer is so that it can fill it, hence (void **), a pointer to a pointer, being the address of your pointer, &data.
When you have received it, you know as the developer that what it points to is actually a uint_32 value so you copy the void pointer into one that points to a uint_32. In fact, this step is unnecessary since you could have cast the uint_32 pointer to void** in the above call but we'll let that slide.
Now that you have told the compiler that the pointer points to a 32 bit number, you can take the number on the other end of that pointer (*op) and store it in a local variable. Again, unnecessary, as *op could be used anywhere num is subsequently used.
Hope this helps.
I'm trying to create a thin wrapper of Windows MMDevice API for Go, and I faced the problem about Windows data types for strings.
According to the documentation of IMMDevice::GetId method, it takes the parameter below:
HRESULT GetId(
[out] LPWSTR *ppstrId
);
And here is my Go code that corresponds to the method above. (github.com/moutend/ywca/immdevice_windows.go:13)
func getId(mmd *IMMDevice, strId *uint16) (err error) {
hr, _, _ := syscall.Syscall(
mmd.VTable().GetId,
2,
uintptr(unsafe.Pointer(mmd)),
uintptr(unsafe.Pointer(strId)),
0)
// ...
}
My understand is that the LPWSTR is the pointer to the array of uint16 values, but it causes invalid pointer error.
What type should I use in this case? Thanks.
It is a pointer to a pointer. The LPWSTR type is a wchar_t* and therefor the parameter in that method is a wchar_t**.
You are not passing in a string buffer for the method to fill. The method will allocate memory with CoTaskMemAlloc and return this memory address back to you after it has been filled. You are responsible for freeing this memory with CoTaskMemAlloc.
The first thing to do is read the documentation for the Windows function.
IMMDevice::GetId
method,
HRESULT GetId(
[out] LPWSTR *ppstrId
);
Parameters
ppstrId [out]
Pointer to a pointer variable into which the method writes the address
of a null-terminated, wide-character string containing the endpoint
device ID. The method allocates the storage for the string. The caller
is responsible for freeing the storage, when it is no longer needed,
by calling the CoTaskMemFree function. If the GetId call fails,
*ppstrId is NULL. For information about CoTaskMemFree, see the Windows SDK documentation.
Return value
If the method succeeds, it returns S_OK. If it fails, possible return
codes include, but are not limited to, the values shown in the
following table.
In particular, "ppstrId [out] Pointer to a pointer variable ..." You have strId *uint16 or *pstrId when I would expect you to have strId **uint16 or *ppstrId.
When I'm creating an integer variable in Processing, should I use int or Integer? They both seem to work the same way. Is it optional which one you would use?
// The same thing?
int a = 5;
Integer b = 4;
// I prefer Integer because it looks like String:
Integer c = 95;
String d = "Hello!";
// Then again, int looks like char:
int e = 3;
char f = 'a';
I'm thinking it's probably just what one prefers, though int is used more?
They have different uses. int is a primitive type while Integer is an object.
The primitive int has a default value of 0 while an Integer will default to null. Primitives use much less memory, just one location of memory, taking up 32 or 64 bits. An object requires more overhead.
Stick to using an int unless you have a need for a null integer or some other requirement.
For reference:
https://processing.org/reference/int.html
https://processing.org/tutorials/objects/
The int type is a primitive data type. That means you can use it in any place you can use a primitive literal, which you can think of as a typed-out number, like 1, 2, 3, 99, -15, etc.
However, you can't use an int in places you have to use an Object. For example, this code will not compile:
void setup(){
ArrayList<int> list = new ArrayList<int>();
}
This code won't compile, because the generic arguments require a class, and int is a primitive, not a class. So how do we get an ArrayList of ints?
That's where primitive wrapper Objects come into play. They are Objects that wrap a primitive, such as int. That way you can correct the above code:
void setup(){
ArrayList<Integer> list = new ArrayList<Integer>();
}
Other primitive wrapper classes include Float, Boolean, Character, etc.
However, it gets more complicated thanks to auto-boxing and auto-unboxing. Basically, Java (and therefore Processing) will automatically convert between primitive values and their primitive wrapper classes. That's why you can do stuff like this:
void setup(){
int primitive = 7;
Integer wrapper = 7;
println(primitive == wrapper);
}
So, for your purposes, it probably doesn't matter which one you use because Java (and therefore Processing) will automatically convert it for you.
However, using Integer instead of int might create Objects that you don't really need, and more importantly, it might prevent you from using Processing.js mode.
Recommended reading:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
http://en.wikipedia.org/wiki/Primitive_wrapper_class
http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
I would like to use MS function to send data.
I didnt find examples where they send other type of data other than const char * .
I tried to send a int, or other, but I failed.
WSASend() and send() both function only take a Char* parameters.
How should i proceed ?
Thanks
Its just a pointer to a buffer, this buffer may contains anything you want.
This char pointer is actually an address to a bytes array, this function requires a length parameter too.
An integer is a 2/4 (short/long) bytes value,
Then if you want to send an integer variable (for example) you have to pass its address, and its length.
WSASend and send are simple functions that send a memory block.
I assume you are talking about C, you have to understand that C's char variables are bytes - 8 bits block, char variables contain any value between 0 and 255.
A pointer to a char var is an address to a byte (which maybe the first cell of a bytes array).
I think thats what confuses you.
I hope you understand.
The const char* parameter indicates that the function is taking a pointer to bytes. Witch really seems to be the result of the original socket api designers being pedantic - C has a generic type to handle any kind of pointer without explicit casts: void*.
You could make a convenience wrapper for send like this - which would allow you to send any (contiguous) thing you can make a pointer to:
int MySend(SOCKET s, const void* buf, int len,int flags)
{
return send(s,(const char*)buf,len,flags);
}
Using void* in place of char* actually makes the api safer, as it can now detect when you do something stupid:
int x=0x1234;
send(s,(const char*)x,sizeof(x),0); // looks right, but is wrong.
mysend(s,x,sizeof(x),0); // this version correctly fails
mysend(s,&x,sizeof(x),0); // correct - pass a pointer to the buffer to send.
WSASend is a bit more tricky to make a convenience wapper for as you have to pass it an array of structs that contain the char*'s - but again its a case of defining an equivalent struct with const void*'s in place of the const char*'s and then casting the data structures to the WSA types in the convenience wrapper. Get it right once, and the rest of the program becomes much easier to determine correct as you don't need casts everywhere hiding potential bugs.