Convert int to const char * - cocos2d-x

In this code:
this->_label = CCLabelTTF::labelWithString(number,"Artial", 32);
number is 5, but must be a const char *.
How can I convert number from an int to the required const char *?

The only three-argument call listed here is:
+ (id) labelWithString: (NSString *) string
fontName: (NSString *) name
fontSize: (CGFloat) size
That means number should not be an int but should indeed be a const char *.
If you want to populate it with the string "5" instead of the integer 5, you'll need to convert it to a string first.
Depending on the language you're using, this could be something like:
char buffer[20];
sprintf (buffer, "%d", number);
(for C) or using something like stringstreams in C++.

Related

Call C function in DLL that returns char * from MS-Access VBA

I have a DLL with a function declared like this:
char * __declspec(dllexport) WINAPI test(int x);
I want to call it in Access VBA like this:
Private Declare Function "test" Lib "MyDLL.dll"(ByVal x As Long) As String
Sub MySub
Dim s As String
s = test(1)
End Sub
Based on articles found in Google, I wrote a function in the DLL:
BSTR CStrToVBStr(char *str)
{
int wslen = MultiByteToWideChar(CP_ACP, 0, str, lstrlen(str), 0, 0);
BSTR bstr = SysAllocStringLen(0, wslen);
MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
return bstr;
}
After the call to test(), s apparently contains Unicode characters. That is, a char * "test" is returned to VBA so that Mid(s, 1, 1) = "t", Mid(s, 2, 1) = Chr(0), Mid(s, 3, 1) = "e", etc. I decide to skip the conversion to Unicode and wrote CstrToVBStr as
BSTR CStrToVBStr(char *str)
{
return SysAllocString(str);
}
and ignored the warning that SysAllocString takes an OLECHAR * and not a char * parameter.
The returned string looks good now, but the null character terminator is included, so if the char * is "test", then in VBA len(s) = 5 and Right(s,1) = Chr(0).
What is the right way to do what I am doing? All examples that I have seen are about char * as parameters, not return values. I can change test() to be
void __declspec(dllexport) WINAPI test(int x, char *result);
but I would like to know if what I am trying to do is possible.
I am using Access 2007 on Windows 7 (64-bit).
A char is the same as an integer. In VBA that means a long (as VBA uses 16 bit terminology). There are no strings involved. To convert an integer or char to a string use chr(x).

mysql_real_escape_string including slashes in output (C, not PHP)

I've seen this question several times relating to PHP (here is an example). The answer was generally 'stop using magic quotes'. I am having this problem in C however. When I insert binary data into a BLOB in my MySQL database, having run it through mysql_real_escape_string(), some 5c ('\') characters appear in the blob. This disrupts the data and makes it unusable. How can I prevent / fix this?
#define CHUNK_SZ (1024*256)
void insertdb(int16_t *data, size_t size, size_t nmemb)
{
static int16_t *buf;
static unsigned long index;
static short initialized;
unsigned long i;
struct tm *info;
time_t rawtime;
char dbuf[12];
char tbuf[12];
char *chunk;
if(initialized==0){
buf = (int16_t *) malloc(CHUNK_SZ);
initialized = 1;
}
if(index + (nmemb*size) + 1 >= CHUNK_SZ || do_exit == 1){
time(&rawtime);
info = localtime(&rawtime);
snprintf(dbuf, 16, "%d-%02d-%02d", 1900+info->tm_year, 1+info->tm_mon, info->tm_mday);
snprintf(tbuf, 16, "%02d:%02d:%02d", info->tm_hour, info->tm_min, info->tm_sec);
chunk = (char *) malloc(index*2+1);
mysql_real_escape_string(con, chunk, (char *) buf, index);
char *st = "INSERT INTO %s (date, time, tag, data) VALUES ('%s', '%s', %d, '%s')";
int len = strlen(st)+strlen(db_mon_table)+strlen(dbuf)+strlen(tbuf)+sizeof(tag)+index*2+1;
char *query = (char *) malloc(len);
int qlen = snprintf(query, len, st, our_table, dbuf, tbuf, tag, chunk);
if(mysql_real_query(con, query, qlen)){
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(1);
}
free(chunk);
index = 0;
} else {
memcpy((void *) buf+index, (void *) data, nmemb*size);
index += (nmemb*size);
}
return;
}
EDIT: Please look here. They use the same function to escape binary data (from an image), insert it, and afterward get the same image from the database. That my binary data is somehow different from an image's binary data makes no sense to me.
If you're inserting into a BLOB column, then instead of escaping the data via mysql_real_escape_string(), you should probably express it as a HEX string. You will have to figure out how to encode your int16_t data into the needed byte sequence, as at minimum you have a byte-order question to sort out (but if you're in control of both encoding and decoding then you just need to make them match).
Alternatively, if the data are genuinely textual, rather than binary, then the type of the column should probably be Text rather than BLOB. In that case, you should continue to use an ordinary SQL string and mysql_real_escape_string().

Allocating array of strings in cuda

Let us assume that we have the following strings that we need to store in a CUDA array.
"hi there"
"this is"
"who is"
How do we declare a array on the GPU to do this. I tried using C++ strings but it does not work.
Probably the best way to do this is to use structure that is similar to common compressed sparse matrix formats. Store the character data packed into a single piece of linear memory, then use a separate integer array to store the starting indices, and perhaps a third array to store the string lengths. The storage overhead of the latter might be more efficient that storing a string termination byte for every entry in the data and trying to parse for the terminator inside the GPU code.
So you might have something like this:
struct gpuStringArray {
unsigned int * pos;
unsigned int * length; // could be a smaller type if strings are short
char4 * data; // 32 bit data type will improve memory throughput, could be 8 bit
}
Note I used a char4 type for the string data; the vector type will give better memory throughput, but it will mean strings need to be aligned/suitably padded to 4 byte boundaries. That may or may not be a problem depending on what a typical real string looks like in your application. Also, the type of the (optional) length parameter should probably be chosen to reflect the maximum admissible string length. If you have a lot of very short strings, it might be worth using an 8 or 16 bit unsigned type for the lengths to save memory.
A really simplistic code to compare strings stored this way in the style of strcmp might look something like this:
__device__ __host__
int cmp4(const char4 & c1, const char4 & c2)
{
int result;
result = c1.x - c2.x; if (result !=0) return result;
result = c1.y - c2.y; if (result !=0) return result;
result = c1.z - c2.z; if (result !=0) return result;
result = c1.w - c2.w; if (result !=0) return result;
return 0;
}
__device__ __host__
int strncmp4(const char4 * s1, const char4 * s2, const unsigned int nwords)
{
for(unsigned int i=0; i<nwords; i++) {
int result = cmp4(s1[i], s2[i]);
if (result != 0) return result;
}
return 0;
}
__global__
void tkernel(const struct gpuStringArray a, const gpuStringArray b, int * result)
{
int idx = threadIdx.x + blockIdx.x * blockDim.x;
char4 * s1 = a.data + a.pos[idx];
char4 * s2 = b.data + b.pos[idx];
unsigned int slen = min(a.length[idx], b.length[idx]);
result[idx] = strncmp4(s1, s2, slen);
}
[disclaimer: never compiled, never tested, no warranty real or implied, use at your own risk]
There are some corner cases and assumptions in this which might catch you out depending on exactly what the real strings in your code look like, but I will leave those as an exercise to the reader to resolve. You should be able to adapt and expand this into whatever it is you are trying to do.
You have to use C-style character strings char *str. Searching for "CUDA string" on google would have given you this CUDA "Hello World" example as first hit: http://computer-graphics.se/hello-world-for-cuda.html
There you can see how to use char*-strings in CUDA. Be aware that standard C-functions like strcpy or strcmp are not available in CUDA!
If you want an array of strings, you just have to use char** (as in C/C++). As for strcmp and similar functions, it highly depends on what you want to do. CUDA is not really well suited for string operations, maybe it would help if you would provide a little more detail about what you want to do.

wrapping byte array data with SWIG array_class

I have a C function that returns an unsigned char * that can either be a pointer to a byte array (binary data representing a File..etc) or a pointer to an array of characters. I'm currently using the SWIG %array_class that wraps all C functions that return an unsigned char pointer and creates a Java array utility (SampleArrayUtil.java) to handle the population and retrieval on the Java side.
My problem is that I also use wrap the unsigned char * using: %apply char * { unsigned char * }; so that I get an array of Strings on the Java side. I don't want to wrap the unsigned char * return value (using %apply char * { unsigned char * };) when I get binary data back, I want to just have the byte array on the Java side. I was thinking of creating another C function to handle the binary data, but I'm unsure how to wrap this new function as it will also return an unsigned char * (see getValueFromRowAsByteArray)
C Functions:
unsigned char * getValueFromRowAsStringArray(struct result_row *row, attribute_type type, int32_t *len)
unsigned char * getValueFromRowAsByteArray(struct result_row *row, attribute_type type, int32_t *len)
//*row* input param with data results, *type* input enum type for the data type being requested and *len* is an output param that contains the length of the data being returned.
SWIG Interface File for Wrapping C Function Returning unsigned char * (array of char):
%module Sample
%include "typemaps.i"
%include "stdint.i"
%include "arrays_java.i"
%include "carrays.i"
%array_class(unsigned char, SampleArrayUtil);
%{
#include "C_API.h"
%}
%apply char * { unsigned char * };
%include "C_API.h"
You can apply different type maps to the same types in different places in at least two ways.
Firstly you can change the active typemap with %apply or %clear, e.g.:
%module test
%include "stdint.i"
%apply intptr_t { unsigned char * };
unsigned char * test1();
%apply char * { unsigned char * };
unsigned char * test2();
%clear unsigned char *;
unsigned char * test3();
Gives three functions in Java with different return types, according to the active typemap.
Secondly you can also write more specific typemaps though, for example:
%apply long long { unsigned char * test4 };
%apply char * { unsigned char * test5 };
unsigned char * test4();
unsigned char * test5();
Only applies to test4 and test5 respectively - it matches on the type and the function name. In Java this results in:
public static long test4() {
return testJNI.test4();
}
public static String test5() {
return testJNI.test5();
}
For arguments you can match on the type and the parameter name in the function signature similarly.

How to pass variable in mysql_query

I try to execute mysql query passing variable. Here is my code
char str[100] = "My String";
mysql_query(conn, printf("INSERT INTO table VALUES %s"), str);
I get that warning during compile process
warning: passing argument 2 of ‘mysql_query’ makes pointer from integer without a cast
What I miss ?
Extending #ckruse's answer, you should take care to use mysql_real_escape_string() if your string comes from arbitrary sources.
int insert_data(MYSQL * mysql, char * str, int len)
{
if (len < 0) {
len = strlen(str);
}
char esc[2*len+1];
unsigned long esclen = mysql_real_escape_string(mysql, esc, str, len);
char statement[512];
snprintf(statement, sizeof statement, "INSERT INTO table VALUES ('%s')", esc);
return mysql_query(mysql, statement);
}
(An alternative could be mysql_hex_string() if dealt with correctly.)
You cannot do that. printf() returns the number of characters printed. You have to create the string before calling mysql_query():
char statement[512], *my_str = "MyString";
snprintf(statement, 512, "INSERT INTO table VALUES ('%s')", str);
mysql_query(conn, statement);
Also, be careful when creating those query strings. Don't use functions like sprintf() if you cannot be sure how long the resulting string is. Don't write over the boundaries of the memory segment.
you should put "'' in front and after the string
like this
mysql_query(conn, printf("INSERT INTO table VALUES ('%s')"), str);