I am trying to use the GetConsoleScreenBufferInfo(HANDLE, PCONSOLE_SCREEN_BUFFER_INFO) function from the Windows API using Perl 6 and (of course) NativeCall.
I think I have set up the CONSOLE_SCREEN_BUFFER_INFO struct the function needs correctly, but the code crashes after the call when I try to dump its content.
This is the shortest (not quite but close) way to demonstrate the problem:
use NativeCall;
constant \HANDLE := Pointer[void];
constant \SHORT := int16;
constant \USHORT := uint16;
constant \WORD := uint16;
constant \DWORD := uint32;
constant \BOOL := int32;
constant \STD_OUTPUT_HANDLE := -11;
constant \STD_INPUT_HANDLE := -10;
class COORD is repr('CStruct') {
has SHORT $.X;
has SHORT $.Y;
}
class SMALL_RECT is repr("CStruct") {
has SHORT $.Left;
has SHORT $.Top;
has SHORT $.Right;
has SHORT $.Bottom;
};
class CONSOLE_SCREEN_BUFFER_INFO is repr("CStruct") {
has COORD $.dwSize;
has COORD $.dwCursorPosition;
has WORD $.wAttributes;
has SMALL_RECT $.srWindow;
has COORD $.dwMaximumWindowSize;
submethod TWEAK {
$!dwSize := COORD.new;
$!dwCursorPosition := COORD.new;
$!srWindow := SMALL_RECT.new;
$!dwMaximumWindowSize := COORD.new;
}
}
# C: BOOL WINAPI GetConsoleScreenBufferInfo(_In_ HANDLE hConsoleOutput, _Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
sub GetConsoleScreenBufferInfo(HANDLE, CONSOLE_SCREEN_BUFFER_INFO is rw) is native("Kernel32.dll") returns BOOL { * };
sub GetStdHandle(DWORD) is native('Kernel32') returns Pointer[void] { * };
my CONSOLE_SCREEN_BUFFER_INFO
$info = CONSOLE_SCREEN_BUFFER_INFO.new;
my HANDLE
$handle-o = GetStdHandle( STD_OUTPUT_HANDLE );
dd $info;
say "GetConsoleScreenBufferInfo ", GetConsoleScreenBufferInfo( $handle-o, $info );
say "Will I live?";
dd $info; #crashes without notice
Any hints as to why the crash occurs and how to fix it are very welcome.
You need to use HAS instead of has for the members of CONSOLE_SCREEN_BUFFER_INFO that are structures as these are embedded instead of referenced by pointer (which is the Perl6 default).
Once you do that, you can drop the TWEAK as well so the code will read
class CONSOLE_SCREEN_BUFFER_INFO is repr("CStruct") {
HAS COORD $.dwSize;
HAS COORD $.dwCursorPosition;
has WORD $.wAttributes;
HAS SMALL_RECT $.srWindow;
HAS COORD $.dwMaximumWindowSize;
}
Related
There is atomicAdd and atomicSub but it seems that atomicMul and atomicDiv don't exist! Is it possible? I need to implement the following code:
atomicMul(&accumulation[index],value)
How Can I do?
Ok, I solved. But I cannot understand how atomicMul works and I don't know how to write it for floats.
#include <stdio.h>
#include <cuda_runtime.h>
__device__ double atomicMul(double* address, double val)
{
unsigned long long int* address_as_ull = (unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
do {
assumed = old;
old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val * __longlong_as_double(assumed)));
} while (assumed != old); return __longlong_as_double(old);
}
__global__ void try_atomicMul(double* d_a, double* d_out)
{
atomicMul(d_out,d_a[threadIdx.x]);
}
int main()
{
double h_a[]={5,6,7,8}, h_out=1;
double *d_a, *d_out;
cudaMalloc((void **)&d_a, 4 * sizeof(double));
cudaMalloc((void **)&d_out,sizeof(double));
cudaMemcpy(d_a, h_a, 4 * sizeof(double),cudaMemcpyHostToDevice);
cudaMemcpy(d_out, &h_out, sizeof(double),cudaMemcpyHostToDevice);
dim3 blockDim(4);
dim3 gridDim(1);
try_atomicMul<<<gridDim, blockDim>>>(d_a,d_out);
cudaMemcpy(&h_out, d_out, sizeof(double), cudaMemcpyDeviceToHost);
printf("%f \n",h_out);
cudaFree(d_a);
return 0;
}
I'll supplement horus' answer based on what I understood about atomicCAS. My answer can be wrong in detail, because I didn't look inside the atomicCAS function but just read the documents about it (atomicCAS, Atomic Functions). Feel free to tackle my answer.
How atomicMul works
According to my understanding, the behavior of atomicCAS(int* address, int compare, int val) is following.
Copy *address into old (i.e old = *address)
Store (old == compare ? val : old) to *address. (At this point, the value of old and *address can be different depending on if the condition matched or not.)
Return old
Understanding about its behavior gets better when we look at the atomicMul function's definition together.
unsigned long long int* address_as_ull = (unsigned long long int*)address;
unsigned long long int oldValue = *address_as_ull, assumed; // Modified the name 'old' to 'oldValue' because it can be confused with 'old' inside the atomicCAS.
do {
assumed = oldValue;
// other threads can access and modify value of *address_as_ull between upper and lower line.
oldValue = atomicCAS(address_as_ull, assumed, __double_as_longlong(val *
__longlong_as_double(assumed)));
} while (assumed != oldValue); return __longlong_as_double(oldValue);
What we want to do is read the value from address(its value is eqaul to address_as_ull), and multiply some value to it and then write it back. The problem is other threads can access and modify value of *address between read, modify, and write.
To ensure there was no intercept of other threads, we check if the value of *address is equal to what we assumed to be there. Say that other thread modified value of *address after assumed=oldValue and oldValue = atomicCAS(...). The modified value of *address will be copied to old variable inside the atomicCAS(see behavior 1. of atomicCAS above).
Since atomicCAS updates *address according to *address = (old == compare ? val : old), *address won't be changed (old==*address).
Then atomicCAS returns old and it goes into oldValue so that the loop can keep going and we can try another shot at next iteration. When *addressis not modified between read and write, then val is written to the *address and loop will end.
How to write it for float
short answer :
__device__ float atomicMul(float* address, float val)
{
int* address_as_int = (int*)address;
int old = *address_as_int, assumed;
do {
assumed = old;
old = atomicCAS(address_as_int, assumed, __float_as_int(val *
__float_as_int(assumed)));
} while (assumed != old); return __int_as_float(old);
}
I didn't test it, so there can be some errors. Fix me if I'm wrong.
How does it work :
For some reason, atomicCAS only supports integer types. So we should manually convert float/double type variable into integer type to input to the function and then re-convert the integer result to float/double type. What I've modified above is double to float and unsigned long long to int because the size of float matches to int.
Kyungsu's answer was almost correct. On the line defining old == atomicCAS(...) though, he used __float_as_int when he should have used __int_as_float. I corrected his code below:
__device__ float atomicMul(float* address, float val){
//Implementation of atomic multiplication
//See https://stackoverflow.com/questions/43354798/atomic-multiplication-and-division
int* address_as_int = (int*)address;
int old = *address_as_int;
int assumed;
do {
assumed = old;
old = atomicCAS(address_as_int, assumed, __float_as_int(val * __int_as_float(assumed)));
} while (assumed != old);
return __int_as_float(old);}
After reading this article, I have some question in mind.
Basically, why we need to store the return value of append() in Go? How is the function actually implemented?
I have tried to replicate (sort of) the mechanism of append in C (which is the first language used to implements the Go language, if I'm not mistaken). I used malloc(), instead of an array as it will not deallocate the slice after the function returns.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct SliceHeader {
int length;
int capacity;
int *zerothElement;
} SliceHeader;
void append(SliceHeader *sh, int element)
{
if (sh->length == sh->capacity) {
// grow capacity size
sh->capacity += 10;
realloc(sh->zerothElement, sh->capacity);
}
sh->zerothElement[sh->length] = element;
sh->length++;
}
SliceHeader * make(int capacity)
{
SliceHeader *sh = (SliceHeader *) malloc(sizeof(sh));
sh->length = 0;
sh->capacity = capacity;
sh->zerothElement = (int *) malloc(capacity * sizeof(int));
return sh;
}
int main()
{
SliceHeader *sh = make(3);
append(sh, 5);
append(sh, 10);
append(sh, 15);
append(sh, 20); // exceed the original capacity, should reallocate
for (int i = 0; i < sh->length; i++) {
printf("%d\n", *((sh->zerothElement)+i) );
}
free(sh->zerothElement);
free(sh);
return 0;
}
(I omit NULLs checking to show only the relevant part to the main question).
If I'm using this code, I can use append() without the need to store its return value and no needs to create a new slice header.
So how is the implementation of append() function in Golang that makes it needs to store a new slice header? Even if the zerothElement uses an array, doesn't it means that it will need to change the array only instead of the whole slice header?
What am I missing here?
Thanks :)
Basically, why we need to store the return value of append() in Go?
You only need to store this value if you intend to use the slice with the appended value.
How is the function actually implemented?
Go is open source, just consult the source code. (Btw: This is uninteresting.)
THTTPRIO component, in HTTPWebNode property, when you click in ClientCertificate, Delphi opens a form to choose the certificate and load it's information in the component's propertys. Is this a windows screen? If it is, how can I use it? Today I'm using SecureBlackBox to load the certificates in a combobox, but I'd like to know if is possible to use this screen.
Thanks
UPDATE
I was able to show the dialog using the ms function CryptUIDlgSelectCertificateFromStore, using JWAPI. Now I'm having problems with the result of the function, the PCCERT_CONTEXT structure.
var
P: Pointer;
Context: PCCERT_CONTEXT;
Issuer: DATA_BLOB;
function GetDataBlobText(Data: DATA_BLOB): string;
begin
SetString(Result, PAnsiChar(Data.pbData), Data.cbData div SizeOf(AnsiChar));
end;
begin
P := CertOpenSystemStore(0, 'MY');
Context := CryptUIDlgSelectCertificateFromStore(P, 0, PChar('test'), nil, CRYPTUI_SELECT_ISSUEDTO_COLUMN, 0, nil);
if Context <> nil then
begin
Issuer := Context.pCertInfo.Issuer;
ShowMessage((GetDataBlobText(Issuer)));
end;
end;
The result in ShowMessage is:
UPDATE2
Thanks #RbMm.
To get string of ASN encoding fields (Issuer and Subject)
var
P: Pointer;
Context: PCCERT_CONTEXT;
Subject: DATA_BLOB;
SubjectStr: string;
size : Cardinal;
begin
P := CertOpenSystemStore(0, PAnsiChar('MY'));
Context := CryptUIDlgSelectCertificateFromStore(P, 0, 'test', 'select certificate',
CRYPTUI_SELECT_ISSUEDTO_COLUMN, 0, nil);
if Context <> nil then
begin
Subject := Context.pCertInfo.Subject;
size := CertNameToStr(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, #Subject, CERT_X500_NAME_STR, 0, 0);
SetString(SubjectStr, PAnsiChar(Subject.pbData), size);
CertNameToStr(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, #Subject, CERT_X500_NAME_STR, PAnsiChar(SubjectStr), size);
Result := SubjectStr;
end;
To get the string of raw data block (SerialNumber):
var
SerialNumber: CRYPT_INTEGER_BLOB;
size : Cardinal;
s: PWideChar;
ss: string;
begin
SerialNumber := Context.pCertInfo.SerialNumber;
CryptBinaryToStringW(SerialNumber.pbData, SerialNumber.cbData, CRYPT_STRING_HEX, nil, size);
s := AllocMem(SizeOf(Char) * size);
CryptBinaryToStringW(SerialNumber.pbData, SerialNumber.cbData, CRYPT_STRING_HEX, s, size);
ss := s;
showmessage(ss);
FreeMem(s, SizeOf(Char) * size);
all data blobs in certificate is encoded. so you need decode it. in general by using CryptDecodeObjectEx api. however for Issuer ( i.e. CERT_NAME_BLOB) decode you can use also CertNameToStrW. only after converts an encoded name in a CERT_NAME_BLOB structure to a null-terminated character string you can print it. code example on c/c++:
void PrintIssuer(PCCERT_CONTEXT Context)
{
CERT_NAME_BLOB Issuer = Context->pCertInfo->Issuer;
// option #1
if (ULONG len = CertNameToStrW(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &Issuer, CERT_X500_NAME_STR, 0, 0))
{
PWSTR sz = (PWSTR)alloca( len * sizeof(WCHAR));
if (CertNameToStrW(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &Issuer, CERT_X500_NAME_STR, sz, len))
{
DbgPrint("%S\n", sz);
}
}
// option #2
PCERT_NAME_INFO pcni;
ULONG size;
if (CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_NAME, Issuer.pbData, Issuer.cbData,
CRYPT_DECODE_ALLOC_FLAG, 0, &pcni, &size))
{
if (DWORD cRDN = pcni->cRDN)
{
PCERT_RDN rgRDN = pcni->rgRDN;
do
{
if (DWORD cRDNAttr = rgRDN->cRDNAttr)
{
PCERT_RDN_ATTR rgRDNAttr = rgRDN->rgRDNAttr;
do
{
DbgPrint("ObjId = %s\n", rgRDNAttr->pszObjId);
switch (rgRDNAttr->dwValueType)
{
case CERT_RDN_PRINTABLE_STRING:
DbgPrint("Value = %s\n", rgRDNAttr->Value.pbData);
break;
}
} while (rgRDNAttr++, --cRDNAttr);
}
} while (rgRDN++, --cRDN);
}
LocalFree(pcni);
}
}
and output
CN=***
ObjId = 2.5.4.3
Value = ***
(the string after CN= and Value = is the same)
you can note that "2.5.4.3" is szOID_COMMON_NAME or "CN". so first api is append CN= before Issuer name. second variant return you name as is and additional ObjId = 2.5.4.3
convert SerialNumber to printable string can next way:
CRYPT_INTEGER_BLOB SerialNumber = Context->pCertInfo->SerialNumber;
DWORD cb = 0;
if (CryptBinaryToStringW(SerialNumber.pbData, SerialNumber.cbData, CRYPT_STRING_HEX, 0, &cb))
{
PWSTR sz = (PWSTR)alloca( cb * sizeof(WCHAR));
if (CryptBinaryToStringW(SerialNumber.pbData, SerialNumber.cbData, CRYPT_STRING_HEX, sz, &cb))
{
DbgPrint("%S\n", sz);
}
}
first of all I admit I'm a newbie in C++ addons for node.js.
I'm writing my first addon and I reached a good result: the addon does what I want. I copied from various examples I found in internet to exchange complex data between the two languages, but I understood almost nothing of what I wrote.
The first thing scaring me is that I wrote nothing that seems to free some memory; another thing which is seriously worrying me is that I don't know if what I wrote may helps or creating confusion for the V8 garbage collector; by the way I don't know if there are better ways to do what I did (iterating over js Object keys in C++, creating js Objects in C++, creating Strings in C++ to be used as properties of js Objects and what else wrong you can find in my code).
So, before going on with my job writing the real math of my addon, I would like to share with the community the nan and V8 part of it to ask if you see something wrong or that can be done in a better way.
Thank you everybody for your help,
iCC
#include <map>
#include <nan.h>
using v8::Array;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Value;
using v8::String;
using Nan::AsyncQueueWorker;
using Nan::AsyncWorker;
using Nan::Callback;
using Nan::GetFunction;
using Nan::HandleScope;
using Nan::New;
using Nan::Null;
using Nan::Set;
using Nan::To;
using namespace std;
class Data {
public:
int dt1;
int dt2;
int dt3;
int dt4;
};
class Result {
public:
int x1;
int x2;
};
class Stats {
public:
int stat1;
int stat2;
};
typedef map<int, Data> DataSet;
typedef map<int, DataSet> DataMap;
typedef map<float, Result> ResultSet;
typedef map<int, ResultSet> ResultMap;
class MyAddOn: public AsyncWorker {
private:
DataMap *datas;
ResultMap results;
Stats stats;
public:
MyAddOn(Callback *callback, DataMap *set): AsyncWorker(callback), datas(set) {}
~MyAddOn() { delete datas; }
void Execute () {
for(DataMap::iterator i = datas->begin(); i != datas->end(); ++i) {
int res = i->first;
DataSet *datas = &i->second;
for(DataSet::iterator l = datas->begin(); l != datas->end(); ++l) {
int dt4 = l->first;
Data *data = &l->second;
// TODO: real population of stats and result
}
// test result population
results[res][res].x1 = res;
results[res][res].x2 = res;
}
// test stats population
stats.stat1 = 23;
stats.stat2 = 42;
}
void HandleOKCallback () {
Local<Object> obj;
Local<Object> res = New<Object>();
Local<Array> rslt = New<Array>();
Local<Object> sts = New<Object>();
Local<String> x1K = New<String>("x1").ToLocalChecked();
Local<String> x2K = New<String>("x2").ToLocalChecked();
uint32_t idx = 0;
for(ResultMap::iterator i = results.begin(); i != results.end(); ++i) {
ResultSet *set = &i->second;
for(ResultSet::iterator l = set->begin(); l != set->end(); ++l) {
Result *result = &l->second;
// is it ok to declare obj just once outside the cycles?
obj = New<Object>();
// is it ok to use same x1K and x2K instances for all objects?
Set(obj, x1K, New<Number>(result->x1));
Set(obj, x2K, New<Number>(result->x2));
Set(rslt, idx++, obj);
}
}
Set(sts, New<String>("stat1").ToLocalChecked(), New<Number>(stats.stat1));
Set(sts, New<String>("stat2").ToLocalChecked(), New<Number>(stats.stat2));
Set(res, New<String>("result").ToLocalChecked(), rslt);
Set(res, New<String>("stats" ).ToLocalChecked(), sts);
Local<Value> argv[] = { Null(), res };
callback->Call(2, argv);
}
};
NAN_METHOD(AddOn) {
Local<Object> datas = info[0].As<Object>();
Callback *callback = new Callback(info[1].As<Function>());
Local<Array> props = datas->GetOwnPropertyNames();
Local<String> dt1K = Nan::New("dt1").ToLocalChecked();
Local<String> dt2K = Nan::New("dt2").ToLocalChecked();
Local<String> dt3K = Nan::New("dt3").ToLocalChecked();
Local<Array> props2;
Local<Value> key;
Local<Object> value;
Local<Object> data;
DataMap *set = new DataMap();
int res;
int dt4;
DataSet *dts;
Data *dt;
for(uint32_t i = 0; i < props->Length(); i++) {
// is it ok to declare key, value, props2 and res just once outside the cycle?
key = props->Get(i);
value = datas->Get(key)->ToObject();
props2 = value->GetOwnPropertyNames();
res = To<int>(key).FromJust();
dts = &((*set)[res]);
for(uint32_t l = 0; l < props2->Length(); l++) {
// is it ok to declare key, data and dt4 just once outside the cycles?
key = props2->Get(l);
data = value->Get(key)->ToObject();
dt4 = To<int>(key).FromJust();
dt = &((*dts)[dt4]);
int dt1 = To<int>(data->Get(dt1K)).FromJust();
int dt2 = To<int>(data->Get(dt2K)).FromJust();
int dt3 = To<int>(data->Get(dt3K)).FromJust();
dt->dt1 = dt1;
dt->dt2 = dt2;
dt->dt3 = dt3;
dt->dt4 = dt4;
}
}
AsyncQueueWorker(new MyAddOn(callback, set));
}
NAN_MODULE_INIT(Init) {
Set(target, New<String>("myaddon").ToLocalChecked(), GetFunction(New<FunctionTemplate>(AddOn)).ToLocalChecked());
}
NODE_MODULE(myaddon, Init)
One year and half later...
If somebody is interested, my server is up and running since my question and the amount of memory it requires is stable.
I can't say if the code I wrote really does not has some memory leak or if lost memory is freed at each thread execution end, but if you are afraid as I was, I can say that using same structure and calls does not cause any real problem.
You do actually free up some of the memory you use, with the line of code:
~MyAddOn() { delete datas; }
In essence, C++ memory management boils down to always calling delete for every object created by new. There are also many additional architecture-specific and legacy 'C' memory management functions, but it is not strictly necessary to use these when you do not require the performance benefits.
As an example of what could potentially be a memory leak: You're passing the object held in the *callback pointer to the function AsyncQueueWorker. Yet nowhere in your code is this pointer freed, so unless the Queue worker frees it for you, there is a memory leak here.
You can use a memory tool such as valgrind to test your program further. It will spot most memory problems for you and comes highly recommended.
One thing I've observed is that you often ask (paraphrased):
Is it okay to declare X outside my loop?
To which the answer actually is that declaring variables inside of your loops is better, whenever you can do it. Declare variables as deep inside as you can, unless you have to re-use them. Variables are restricted in scope to the outermost set of {} brackets. You can read more about this in this question.
is it ok to use same x1K and x2K instances for all objects?
In essence, when you do this, if one of these objects modifies its 'x1K' string, then it will change for all of them. The advantage is that you free up memory. If the string is the same for all these objects anyway, instead of having to store say 1,000,000 copies of it, your computer will only keep a single one in memory and have 1,000,000 pointers to it instead. If the string is 9 ASCII characters long or longer under amd64, then that amounts to significant memory savings.
By the way, if you don't intend to modify a variable after its declaration, you can declare it as const, a keyword short for constant which forces the compiler to check that your variable is not modified after declaration. You may have to deal with quite a few compiler errors about functions accepting only non-const versions of things they don't modify, some of which may not be your own code, in which case you're out of luck. Being as conservative as possible with non-const variables can help spot problems.
I'm trying to use VkKeyScan from the Window's API, however the program crashes whenever that function is called. I've had no problems with other Window's API functions I've imported and used in this way. Is there something wrong with my syscall.Syscall call?
var (
user32, _ = syscall.LoadLibrary("user32.dll")
vkKeyScan, _ = syscall.GetProcAddress(user32, "VkKeyScan")
)
func VkKeyScan(char byte) (int16, syscall.Errno) {
var nargs uintptr = 1
ret, _, callErr := syscall.Syscall(uintptr(vkKeyScan), nargs, uintptr(char), 0, 0)
return int16(ret), callErr
}
VkScanKey works in C because it’s #defined roughly like this:
#ifdef UNICODE
# define VkScanKey VkScanKeyW
#else
# define VkScanKey VkScanKeyA
#endif
So VkScanKey isn’t the real symbol—VkScanKeyW is, and that’s the only form GetProcAddress will take it in. If you had been doing proper error handling you might have noticed that GetProcAddress was failing rather than Syscall, which might have tipped you off to this fact.