Dynamically Sized Input Buffer for Console Game in C - c

Hey, I'm trying rewrite code in C++ to work in C. I'm basically just trying to find an equivalent for new and delete in C but it's not quite working, here is my code:
Here's the code in C++:
// Gets the number of events
ReadConsoleInput(rHnd, eventBuffer, numEvents, &numEventsRead);
// Sizes the eventbuffer based on the number of events
INPUT_RECORD *eventBuffer = new INPUT_RECORD[numEvents];
// Removes from memory:
delete[] eventBuffer;
Here's what I have so far in C:
// Event buffer
INPUT_RECORD *eventBuffer;
// Gets the number of events
ReadConsoleInput(rHnd, eventBuffer, numEvents, &numEventsRead);
// Sizes the event buffer based on the number of events.
eventBuffer = malloc(numOfEvents * sizeof(*eventBuffer));
// Removes from memory:
free(eventBuffer);
The code above almost works with one error:
Error: a value of type "void *" cannot be assigned to an entity of type "INPUT_RECORD *"

You just have to cast it --
eventBuffer = (INPUT_RECORD*) malloc(numOfEvents * sizeof(*eventBuffer));
Of course, someone is going to come along and say that the standard says you don't have to cast the result of "malloc". Obviously, in this case, the standard is irrelevant :)

Your C++ code doesn't work. You pass eventBuffer to ReadConsoleInput() but it's only later that you declare it:
// Gets the number of events
ReadConsoleInput(rHnd, eventBuffer, numEvents, &numEventsRead);
// Sizes the eventbuffer based on the number of events
INPUT_RECORD *eventBuffer = new INPUT_RECORD[numEvents];
If ReadConsoleInput() needs eventBuffer for something, you'll need to declare it before calling the function.
Anyway, the equivalent C code would be:
INPUT_RECORD* eventBuffer;
ReadConsoleInput(rHnd, eventBuffer, numEvents, &numEventsRead);
eventBuffer = (INPUT_RECORD*) malloc(numOfEvents * sizeof(INPUT_RECORD));

Related

supercollider - access buffer information inside a `Pbind` that uses a buffer array

in brief
i have an array of buffers; those are passed to a synth at random using a Pbind ; i need to access info on the current buffer from within the Pbind but I need help doing that !
explanation of the problem
i have loaded an array of buffers containing samples. those samples must be played in a random order (and at random intervals, but that's for later). to do so, i pass those buffers to a synth inside a Pbind. i want to set the \dur key to be the length of the current buffer being played. the thing is, that i can't find a way to access info on the current buffer from within the Pbind. i have tried using Pkey, Pfset and Plambda, but to no success.
does somebody know how to do this ???
code
the sounds are played using:
SynthDef(\player, {
/*
play a file from a buffer
out: the output channel
bufnum: the buffer to play
*/
arg out=0, bufnum;
Out.ar(
out,
PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), doneAction: Done.freeSelf)) ! 2
)
}).add;
the buffers are loaded in an array:
path = PathName.new("/path/to/files");
bufferArray = Array.new(100);
path.filesDo({
arg file;
bufferArray.add( Buffer.read(s, file.fullPath) );
});
my Pbind pattern works like this:
i define a \buffer value which is a single buffer from the array
i pass this \buffer to my synth
i then try to calculate its duration (\dur) by dividing the number of frames of the buffer by its sample rate. this is what i can't seem to get right
p = Pbind(
\buffer, Prand(bufferArray, inf),
\instrument, \player,
\bufnum, Pkey(\buffer),
\dur, (Pkey(\buffer.numFrames) / Pkey(\buffer.sampleRate))
)
thanks in advance for your help !!
solution to the problem: how to access buffer information inside a Pbind pattern
after hours of searching, i've found a solution to this problem on the supercollider forum, and i'm posting my own solution in case others are looking on here, like i was !
define a global array of buffers
this isn't compulsory, but it allows to only create the buffer array once; the array is created asynchronously using the action parameter of Buffer.read(), which allows to trigger a function once the buffer is loaded:
var path;
Buffer.freeAll; // avoid using all buffers in server
path = PathName.new("/path/to/sound/files");
~bufferArray = Array.new(100);
path.filesDo({
// add the buffer to `~bufferArray` asynchronously
arg file;
b = Buffer.read(s, file.fullPath, action: {
arg buffer;
~bufferArray.add( buffer );
})
});
play the synth and use Pfunc to access buffer information inside of the Pbind
this is the solution per se:
define a Pbind pattern which activates a synth to play the buffer.
inside that, define a \buffer variable to hold the current buffer.
then, access data on that buffer inside of a Pfunc. this generates an argument containing the last event in the Pbind. using this event, the buffer data can be accessed
p = Pbind(
\buffer, Prand(~bufferArray, inf), // randomly access one buffer inside of the array
\instrument, \player,
\bufnum, Pfunc { arg event; event[\buffer] }, // define a `Pfunc` function to access the previous event containing a `\buffer` variable
\dur, Pfunc { arg event; event[\buffer].numFrames / event[\buffer].sampleRate } // duration
);
p.play;
see the original answer on the supercollider forum for more details !

Could not find the entrypoint _pcre2_compile#40. (3260)

I have built a libpcre2-8.dll with the help of this Git Repo.
I'm now trying to access the function pcre2_compile from an ABL (Progress) program. (Progress is an old 4GL Language). I'm constantly hitting the error
Could not find the entrypoint _pcre2_compile#40. (3260)
I've already tried many things but it still doesn't work.
The Dynamic Library is 64 bit and Progress is also running in 64 bit.
In ABL (Progress) you can specify the LIBRARY-CALLING-CONVENTION but whether I set it to STDCALL or CDECL or just don't specify it, the error remains the same.
This is a snippet of the Progress ABL I'm trying to execute the function: (code comes from this Git Repo, which works, but only for 32 bit)
PROCEDURE pcre2_compile :
DEFINE INPUT PARAMETER pattern AS CHARACTER. /* const char * */
DEFINE INPUT PARAMETER options AS INTEGER. /* int */
DEFINE OUTPUT PARAMETER errcodeptr AS INTEGER. /* int * */
DEFINE OUTPUT PARAMETER errptr AS MEMPTR. /* const char ** */
DEFINE OUTPUT PARAMETER erroffset AS MEMPTR. /* int * */
DEFINE INPUT PARAMETER tableptr AS INTEGER. /* const unsigned char * */
DEFINE OUTPUT PARAMETER result AS MEMPTR. /* pcre * */
DEFINE VARIABLE libName AS CHARACTER NO-UNDO.
DEFINE VARIABLE hCall AS HANDLE NO-UNDO.
libName = get-library().
CREATE CALL hCall.
ASSIGN
hCall:CALL-NAME = "pcre2_compile"
hCall:LIBRARY = "lib/libpcre2-8.dll"
//hCall:LIBRARY-CALLING-CONVENTION = "STDCALL"
hCall:CALL-TYPE = DLL-CALL-TYPE
hCall:NUM-PARAMETERS = 6
hCall:RETURN-VALUE-DLL-TYPE = "MEMPTR".
hCall:SET-PARAMETER(1, "CHARACTER", "INPUT" , pattern ).
hCall:SET-PARAMETER(2, "LONG" , "INPUT" , options ).
hCall:SET-PARAMETER(3, "HANDLE TO LONG" , "OUTPUT", errcodeptr ).
hCall:SET-PARAMETER(4, "MEMPTR" , "OUTPUT", errptr ).
hCall:SET-PARAMETER(5, "MEMPTR" , "OUTPUT", erroffset ).
hCall:SET-PARAMETER(6, "LONG" , "INPUT" , tableptr ).
hCall:INVOKE().
ASSIGN result = hCall:RETURN-VALUE.
DELETE OBJECT hCall.
END PROCEDURE.
What am I missing?
Update: Checked with Dependency Walker and the functions seem to be visible. They do have a _8 suffix... But even when trying pcre2_compile_8 it still gives me the same error.
I think that you need to change your long integers to INT64.
Is the entrypoint externally visible/accesible?
I've used https://dependencywalker.com/ in the past to figure that out.
Does that change if you specify the ORDINAL option ?
So the problem was that the name of the entry point was "pcre2_compile_8" instead of "pcre2_compile"... Wanted to delete the question because now it looks quite dumb but leaving it anyway...

How to solve "bad pointer in write barrier" panic in cgo when C library uses opaque struct pointers

I'm currently writing a Go wrapper around a C library. That C library uses opaque struct pointers to hide information across the interface. However, the underlying implementation stores size_t values in there. This leads to runtime errors in the resulting program.
A minimum working example to reproduce the problem looks like this:
main.go:
package main
/*
#include "stddef.h"
// Create an opaque type to hide the details of the underlying data structure.
typedef struct HandlePrivate *Handle;
// In reality, the implementation uses a type derived from size_t for the Handle.
Handle getInvalidPointer() {
size_t actualHandle = 1;
return (Handle) actualHandle;
}
*/
import "C"
// Create a temporary slice containing invalid pointers.
// The idea is that the local variable slice can be garbage collected at the end of the function call.
// When the slice is scanned for linked objects, the GC comes across the invalid pointers.
func getTempSlice() {
slice := make([]C.Handle, 1000000)
for i, _ := range slice {
slice[i] = C.getInvalidPointer()
}
}
func main() {
getTempSlice()
}
Running this program will lead to the following error
runtime: writebarrierptr *0xc42006c000 = 0x1
fatal error: bad pointer in write barrier
[...stack trace omitted...]
Note that the errors disappear when the GC is disabled by setting the environment variable GOGC=off.
My question is which is the best way to solve or work around this problem. The library stores integer values in pointers for the sake of information hiding and this seems to confuse the GC. For obvious reasons I don't want to start messing with the library itself but rather absorb this behaviour in my wrapping layer.
My environment is Ubuntu 16.04, with gcc 5.4.0 and Go 1.9.2.
Documentation of cgo
I can reproduce the error for go1.8.5 and go1.9.2. I cannot reproduce the error for tip: devel +f01b928 Sat Nov 11 06:17:48 2017 +0000 (effectively go1.10alpha).
// Create a temporary slice containing invalid pointers.
// The idea is that the local variable slice can be garbage collected at the end of the function call.
// When the slice is scanned for linked objects, the GC comes across the invalid pointers.
A Go mantra is do not ignore errors. However, you seem to assume that that the GC will gracefully ignore errors. The GC should complain loudly (go1.8.5 and go1.9.2). At worst, with undefined behavior that may vary from release to release, the GC may appear to ignore errors (go devel).
The Go compiler sees a pointer and the Go runtime GC expects a valid pointer.
// go tool cgo
// type _Ctype_Handle *_Ctype_struct_HandlePrivate
// var handle _Ctype_Handle
var handle C.Handle
// main._Ctype_Handle <nil> 0x0
fmt.Fprintf(os.Stderr, "%[1]T %[1]v %[1]p\n", handle)
slice := make([]C.Handle, 1000000)
for i, _ := range slice {
slice[i] = C.getInvalidPointer()
}
Use type uintptr. For example,
package main
import "unsafe"
/*
#include "stddef.h"
// Create an opaque type to hide the details of the underlying data structure.
typedef struct HandlePrivate *Handle;
// In reality, the implementation uses a type derived from size_t for the Handle.
Handle getInvalidPointer() {
size_t actualHandle = 1;
return (Handle) actualHandle;
}
*/
import "C"
// Create a temporary slice of C pointers as Go integer type uintptr.
func getTempSlice() {
slice := make([]uintptr, 1000000)
for i, _ := range slice {
slice[i] = uintptr(unsafe.Pointer(C.getInvalidPointer()))
}
}
func main() {
getTempSlice()
}

using Dynamic array of HANDLE(void*) with createThread(...)

I'm a beginner in C and in threading in particular.
I need to malloc and use dynamic array of HANDLE that later would be used in WaitForMultipleObjects.
What I do now:
int i = 0 ;
HANDLE ThreadHandlers = (HANDLE)malloc(sizeof(HANDLE)* List->logicalLength);
Then in a loop:
while(curr!= NULL)
{
ThreadHandlers[i]= createtestThread((LPTHREAD_START_ROUTINE)executeTest,(TestStruct*)(curr->data),ThreadIds+i);
curr = curr->next;
//ThreadHandlers[i] =
i++;
}
WaitForMultipleObjects(
List->logicalLength,
ThreadHandlers,
TRUE, /* wait until all threads finish */
INFINITE);
But when I try to compile, it I get:
IntelliSense: expression must be a pointer to a complete object type
Which from my understanding is because HANDLE is typedef void*
and I cant do logic with void*.
What workaround can be done?
What is the right way to do that kind of programming? (waiting for unknown amount of threads)
This line:
HANDLE ThreadHandlers = (HANDLE)malloc(sizeof(HANDLE)* List->logicalLength);
Should be this:
HANDLE* ThreadHandlers = (HANDLE*)malloc(sizeof(HANDLE) * List->logicalLength);
That above fix will resolve your compile problem with regards to WaitForMultipleObjects.
And while I'm here, this line looks suspicous:
ThreadHandlers[i]= createtestThread((LPTHREAD_START_ROUTINE)executeTest,(TestStruct*)(curr->data),ThreadIds+i);
I assume createtestthread is a wrapper for CreateThread or _beginthreadex. But if you have to explicitly cast your function explicitly to LPTHREAD_START_ROUTINE, you have probably done something wrong. Remove the cast such that this line becomes:
ThreadHandlers[i]= createtestThread(executeTest,(TestStruct*)(curr->data),ThreadIds+i);
Then if that still leads to a new compiler error, fix the declaration of executeTest such that it's declared as follows:
DWORD __stdcall executeTest(void* pData);
Forcing a function of a different signature into CreateThread will lead to weird problems later on.
You've made a mistake in creation of array of handles, what you should do is:
HANDLE *ThreadHandlers = (HANDLE*)malloc(sizeof(HANDLE) * List->logicalLength);
As far as your second question goes, using WaitForMultipleObjects is the right way to wait for an unknown amount of threads. Depending on the situation, you could pass FALSE as third parameter if you want to wait only until one thread gets signaled, or pass some time-out interval as fourth argument if you want to stop waiting after a certain period.

SetProp problem

Can anybody tell me why the following code doesn't work? I don't get any compiler errors.
short value = 10;
SetProp(hCtl, "value", (short*) value);
The third parameter is typed as a HANDLE, so IMO to meet the explicit contract of the function you should save the property as a HANDLE by allocating a HGLOBAL memory block. However, as noted in the comments below, MSDN states that any value can be specified, and indeed when I try it on Windows 7 using...
SetProp(hWnd, _T("TestProp"), (HANDLE)(10)); // or (HANDLE)(short*)(10)
...
(short)GetProp(hWnd, _T("TestProp"));
... I get back 10 from GetProp. I suspect somewhere between your SetProp and GetProp one of two things happens: (1) the value of hWnd is different -- you're checking a different window or (2) a timing issue -- the property hasn't been set yet or had been removed.
If you wanted to use an HGLOBAL instead to follow the specific types of the function signature, you can follow this example in MSDN.
Even though a HANDLE is just a pointer, it's a specific data type that is allocated by calls into the Windows API. Lots of things have handles: icons, cursors, files, ... Unless the documentation explicitly states otherwise, to use a blob of data such as a short when the function calls for a HANDLE, you need a memory handle (an HGLOBAL).
The sample code linked above copies data as a string, but you can instead set it as another data type:
// TODO: Add error handling
hMem = GlobalAlloc(GPTR, sizeof(short));
lpMem = GlobalLock(hMem);
if (lpMem != NULL)
{
*((short*)lpMem) = 10;
GlobalUnlock(hMem);
}
To read it back, when you GetProp to get the HANDLE you must lock it to read the memory:
// TODO: Add error handling
short val;
hMem = (HGLOBAL)GetProp(hwnd, ...);
if (hMem)
{
lpMem = GlobalLock(hMem);
if (lpMem)
{
val = *((short*)lpMem);
}
}
I would create the short on the heap, so that it continues to exist, or perhaps make it global, which is perhaps what you did. Also the cast for the short address needs to be void *, or HANDLE.

Resources