i have this C++ code in linux ubuntu i want use this method in python by ctype
but can not send parameter to ctype.cdl.funcion
C++ code :
extern "C" unsigned char* getuserdata(int code,unsigned char* globalkey,unsigned char* key)
{
unsigned char data[256];
KeyA *keya;
keya=new KeyA;
keya->OpenDevice(0);
keya->Init(globalkey,globalkey,globalkey,globalkey);
keya->ReadUserMemory( 0,256,key,data);
return data;
}
sample use this function in C++:
unsigned char g_user[16] = { 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 };
unsigned char publickey[16] = { 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55 };
printf("function Return: %s\n", getuserdata(0,publickey,g_user));
and my python source code (not Worked!!) is :
from ctypes import *
dl=cdll.LoadLibrary('/home/iman/KCore/kcore/hkey.so');
dl.getuserdata.restype = c_char_p
string_buffers = [addressof(create_string_buffer(16)) ]
string_buffers[0]= "5555555555555555";
string_buffers2 = [addressof(create_string_buffer(16)) ]
string_buffers2[0]="2222222222222222";
st= dl.getuserdata(0,string_buffers,string_buffers2);
print st+"\n";
Let's look at the code...
string_buffers = [addressof(create_string_buffer(16)) ]
This line creates a Python list containing the address of a 16-byte string buffer (or maybe it's not bytes but characters, please find that out yourself).
string_buffers[0]= "5555555555555555";
This line replaces the pointer from above with the string "555555555555555".
dl.getuserdata(0,string_buffers,string_buffers2);
Here, you pass the list with a string to the function, while the function takes a pointer to bytes. Question is what you want to achieve here, i.e. whether you want the buffer to be written to or not. If not, use const in C++ and simply pass "22222" as parameter, ctypes will do the rest for you automatically.
That said, it could be that I'm guessing wrong, since you haven't explained what exactly is happening (quote the error messages!) and how exactly you determined that something doesn't work. Further, you should clean up your broken C++ code or temporarily replace it with something smaller that is more suitable to explain the exact problem.
Related
I'm learning D language (I know C++ well)... I want to do some Windows specific stuff so I wrote this just to try out the API:
import core.sys.windows.windows;
import std.stdio;
string name()
{
char buffer[100];
uint size = 100;
GetComputerNameA(&buffer[0], &size);
return buffer;
}
void main()
{
writeln(name());
}
I get in my return statement:
test.d(11): Error: cannot implicitly convert expression (buffer) of type char[100] to string
Ok, in C++ it would call the constructor to make a string. It says implicit so lets cast it with a C style cast: return (string)buffer;.
test.d(11): Error: C style cast illegal, use cast(string)buffer
Ah ok, I remember, different syntax.
return cast(string)buffer;
Now it compiles but I just get garbage.
I assume that is is because it's storing a pointer in the string to the temporary buffer. I don't want to do this, I want to copy the characters into a string but annoyingly I can't seem to find how to do this?
So questions:
How do I construct an actual string from a char array that allocates storage properly? (Copies the characters)
Allocating a buffer of a random size like this and converting to a string seems ugly. Is there a proper way to do this in D? (I'm talking about the general question, not specifically this API just in case there is another API to get the computer name).
If either of those are answered in a manual where should I have looked to find details?
Thanks for any help and advice.
I think you need:
string name()
{
char buffer[100];
uint size = 100;
GetComputerNameA(buffer.ptr, &size);
return buffer[0 .. size].idup;
}
buffer.idup is the standard way to get an immutable copy. For this case, since you want a dynamically-sized string (and recall that string is really just shorthand for immutable(char)[]), you want buffer[0..size].idup, using D's array slicing.
See http://dlang.org/arrays.html for more information.
(This is a bit of a nitpick, but you may want to use buffer.ptr instead of &buffer[0], mostly for readability's sake.)
I have two functions and I'm trying to pass a buffer from one function to the other and have it modify the contents, but I cannot seem to get it to work..here is what i have:
void caller ()
{
char * datum;
populate (&datum);
}
void populate (void * buf)
{
unsigned char * datump;
int dtsz;
getData (datump,dtsz); // This function puts "001" in datump and dtsz = 4
buf = new unsigned char[dtsz];
memset(datumbuf,0,sizeof(buf));
memcpy (buf,datump,dtsz);
}
When I debug through everything seems to be exactly like it should be until I get to memcpy. It does not seem like memcpy actually does anything.
The reason "datumbuf = new unsigned char[dtsz]" is done is because the "getData()" function returns each time with a different size depending on the data size, hence the size can't be statically assigned.
When I get back to the main "caller()" function, the "datum" contains junk.
Any ideas why this is happening and how it can be fixed?
Thanks
It's not C++, it's C. Use std::string and forget about such buffers if you're using C++.
You don't modify buf in populate. You don't allocate memory for datump (don't know what getData does).
Your populate function should just return a pointer. that way everything is much easier.
char * populate()
{
...
buf = new unsigned char[dtsz];
...
return buf;
}
...and then you call it like this:
char * datum = populate()
your current code doesn't work because you're confused between value and reference parameters. You pass datum 'by reference' populate(&datum) but `populate treats it like a value parameter.
That memset line is strange and wrong, sizeof(datumbuf) is the pointer size (4 or 8), not the arrays length.
If its 8, it will be writing over other stuff, since the array you describe is only 4 long. Still, I doubt thats your actual error.
I'm making an unmanaged C++ DLL which uses the C# managed DLL. I'm writting the C++ library as I need to use functions and headers defined in a software for which the C++ library can be added as an addon. But the things I want to make are so complex that my sparse knowledge of C++ would slow me down so I decided to do things in my favourite C# and connect the DLLs via COM and I was successful.
I'm somehow successful in making the code work, but less successful in keeping the code concise as I'm clearly not a professional C++ programmer.
The problem is with converting various string types. BSTR and const char * in particular.
The following code converst const char * to BSTR:
BSTR bstrt;
const char * someChar;
csharpInterfacedClassPointer->get_PropertyForSomeChars(&bstrt);
strcpy_s(nstring, (char *)bstrt);
someChar = nstring;
The problem is, I have plenty of discrete someChars with corresponding discrete interface methods...the property method is generated from the C# interface so I can't change it. Each of the "someChar" requires the following three lines of code so for 30 discrete variables, I'd need to write 90 lines of code.
csharpInterfacedClassPointer->get_PropertyForSomeCharX(&bstrt);
strcpy_s(nstring, (char *)bstrt);
someCharX = nstring;
The question is: how do write some shortcut for this so it'd fit just in one line?
I tried some sort of function with the "getter" function pointer and the someChar pointer.
typedef HRESULT (__stdcall *get_string_func)(BSTR * str); //getter function pointer
//the converting function
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
const size_t nsize = 1000;
char nstring[nsize];
BSTR bstrt;
bstrt = bstr_t(constCharString);
bstr_get_fx(&bstrt);
strcpy_s(nstring, (char *)bstrt);
constCharString = nstring;
}
//calling the function...as I thought that would work
ConvertAndAssign(sPtr->get_DataFile, someChar);
But then the compiler says some weird things aboud bound functions and how they are not allowed as pointers...I googled what does it mean and the solutions given required to alter the function definition but I can't do that since the definition is generated from the C# code (by regasm.exe).
Important note: I need to get the const char * type in the end because it is the required input type to the functions of the program for which I'm making the C++ DLL.
Disclaimer: it was a long time (7 years to be more precise) since I have touched C++/COM code for the last time.
Regarding binding an instance method to a function pointer check this SO question.
Another option is to use the IDispatch interface (if your COM component implement it)
Regarding ConvertAndAssign() implementation, IMO it has some issues. In order to make it easier to explain I have copied it bellow:
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
const size_t nsize = 1000;
char nstring[nsize];
BSTR bstrt;
bstrt = bstr_t(constCharString); // issue 1
bstr_get_fx(&bstrt);
strcpy_s(nstring, (char *)bstrt); // issue 2
constCharString = nstring; // issues 3 & 4
}
if your COM method returns a BSTR (i.e, it has an out parameter of type BSTR) you should not pass on a pre-allocated string otherwise you'll end up
leaking memory.
Casting bstr to char * will not work. BSTRs are Unicode strings. Also they are encoded such its length preceeds the actual characters.
If you are using ATL/MFC you can use one of the string conversion macros.
If you are NOT using ATL/MFC you can use WideCharToMultiByte() function or one of the "Smart" BSTR classes (CComBSTR in ATL, bstr_t, etc)
Assigning nstring to constCharString will have no effect on the outside string. If you are calling ConvertAndAssign like follows
char *outsideStr = NULL;
ConvertAndAssign(whatever, outsideStr);
Inside ConvertAndAssign() function consCharString will point to NULL in the begning. After the assignment constCharString does point to nstring but
outsideStr still points to NULL (remember, when you called ConvertAndAssign() function a copy of the pointer value was passed to it).
In order to get what you want you can either pass a reference or a pointer to a pointer:
void ConvertAndAssign(get_string_func bstr_get_fx, const char * &constCharString)
{
constCharString = nstring; // Assignment
}
or a pointer to a pointer:
char *outsideStr = NULL;
ConvertAndAssign(whatever, &outsideStr);
void ConvertAndAssign(get_string_func bstr_get_fx, const char **constCharString)
{
.
.
.
*constCharString = nstring; // Assignment
}
After fixing the previous issue you'll hit another one: You cannot return the address of a local variable! When your code resumes after ConvertAndAssign() returns, this
address is not allocated for you anymore (it's part of the stack, so it may even look to be working, but I assure you, it is not; the slightest changes
in your code may break it)
To fix this you need to pass a pre-allocated string:
char outsideStr[1000];
ConvertAndAssign(whatever, outsideStr);
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
strcpy_s(constCharString, /* result str here */ );
}
or allocate a string in the heap.
Given all the above, one possible implementation for ConvertAndAssign() and its usage is as follow:
char outsideStr[1000];
ConvertAndAssign(whatever, outsideStr);
void ConvertAndAssign(get_string_func bstr_get_fx, const char * constCharString)
{
BSTR bstrt;
if(SUCCEEDED(bstr_get_fx(&bstrt)))
{
// Assumes constCharString points to a buffer large enough to hold the converted string.
strcpy_s(constCharString, CW2A(bstr)); // not completely correct since bstr may contain the byte 0 but I guess thats not your scenario.
SysFreeString(bstr);
}
else
{
// error handling.
constCharString[0] = 0;
}
}
This question can be deleted if any mod is going to read this. I realized I have a totally different problem. Thanks Vagaus for his effort.
I've got a programming question about the implementation of strcat() function.
I have been trying to solve that problem and I got some Access violation error.
My created function:
char str_cat(char str1, char str2)
{
return str1-'\0'+str2;
}
what is wrong in the above code?
One more question please,
is "iostream" a header file? where can I get it?
thanks
Unfortunately, everything is wrong with this function, even the return type and argument types. It should look like
char * strcat(const char *str1, const char *str2)
and it should work by allocating a new block of memory large enough to hold the concatenated strings using either malloc (for C) or new (for C++), then copy both strings into it. I think you've got your (home)work cut out for you, though, as I don't think you know much of what any of that means.
Nothing is right in the above code.
You need to take char * parameters
You need to return a char * if you have to return something (which isn't needed)
You'll need to loop over the string copying individual characters - no easy solution with + and -
You'll need to 0-terminate the result
E.g. like this:
void strcat(char * Dest, char const * Src) {
char * d = Dest;
while (*d++);
char const * s = Src;
while (*s) { *d++ = *s++; }
*d = 0;
}
Why do you need to do this? There's a perfectly good strcat in the standard library, and there's a perfectly good std::string which you can use + on.
Don't want to sound negative but there is not much right with this code.
Firstly, strings in C are char*, not char.
Second, there is no way to 'add' or 'subtract' them the way you would hope (which is sort of kind of possible in, say, python).
iostream is the standard I/O header for C++, it should be bundled with your distribution.
I would really suggest a tutorial on pointers to get you going - this I found just by googling "ansi c pointers" - I'm guessing the problem asks you for a C answer as opposed to C++, since in C++ you would use std::string and the overloaded operator+.
I feel like this is a really silly question, but I can't seem to find an answer anywhere!
Is it possible to get a group of chars from a char array? to throw down some pseudo-code:
char arry[20] = "hello world!";
char part[10] = arry[0-4];
printf(part);
output:
hello
So, can I get a segment of chars from an array like this without looping and getting them char-by-char or converting to strings so I can use substr()?
You could use memcpy (or strncpy) to get a substring:
memcpy(part, arry + 5 /* Offset */, 3 /* Length */);
part[3] = 0; /* Add terminator */
On another aspect of your code, note that doing printf(str) can lead to format string vulnerabilities if str contains untrusted input.
In short, no. C-style "strings" simply don't work that way. You will either have to use a manual loop, or strncpy(), or do it via C++ std::string functionality. Given that you're in C++, you may as well do everything with C++ strings!
Side-note
As it happens, for your particular example application, you can achieve this simply via the functionality offered by printf():
printf("%.5s\n", arry);
As Oli said, you'd need to use C++ std::string functionality. In your example:
std::string hello("Hello World!");
std::string part(hello.substr(0, 5)); // note it's <start>, <length>, so not '0-4'
std::cout << part;
Well, you do mention the two obvious approaches. The only thing I can think of would be to define your own substring type to work off character arrays:
struct SubArray
{
SubArray(const char* a, unsigned s, unsigned e)
:arrayOwnedElseWhere_(a),
start_(s),
end_(e)
{}
const char* arrayOwnedElseWhere_;
unsigned start_;
unsigned end_;
void print()
{
printf_s("%.*s\n", end_ - start_ + 1, arrayOwnedElseWhere_ + start_);
}
};