How to convert between char* and Platform::String^? - string

How do I convert a string from char* to Platform::String^ and vice versa?
I'm developing a DLL for the Universal Windows Platform, using version 10.0.10586.0 of the SDK and Visual Studio 2015 Update 1.

Not the most elegant but the only solution that worked for me to get const char * from the Platform::String
const char * StringToChar(String^ s) {
const wchar_t *W = s->Data();
int Size = wcslen(W);
char *CString = new char[Size + 1];
CString[Size] = 0;
for (int y = 0;y<Size; y++)
{
CString[y] = (char)W[y];
}
return (const char *)CString;
}
and its a lot easier to convert it back
String^ CharToString(const char * char_array) {
std::string s_str = std::string(char_array);
std::wstring wid_str = std::wstring(s_str.begin(), s_str.end());
const wchar_t* w_char = wid_str.c_str();
return ref new String(w_char);
}

//Char to String
char *text = "new string";
Platform::String str = new Platform::String(text, strlen(text));
//String to char
char16 *newText = str.Data();
More detailed answer: https://stackoverflow.com/a/11746252/5477130

Related

How can I write a qt application to display a dcm image?

I have found a way using vtk to display dcm image. But vtk is too much for what I want, I only want to display a dcm image. The dcmtk will process the dcm image for me.
So is there an easy way for me to display dcm image?
Thanks in advance.
The smallest learning curve and code requirement will likely be to use Grass Roots DICOM. (http://gdcm.sourceforge.net/wiki/index.php/Main_Page) This library will link to Qt and give you a quick way to load an image. The only thing to remember is that a DICOM image file does not contain an image that Qt (or anything else) can display directly. You have to load the DICOM data and convert the image to display it.
These are the lines to add to the project file. Note that the paths will have to match your machine and versions, not mine;
#INCLUDEPATH += /usr/local/include/gdcm-2.4/
#LIBS += -L"/usr/local/lib/" -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMEXD -lgdcmMSFF -lgdcmjpeg12 -lgdcmjpeg16 -lgdcmopenjpeg -lgdcmjpeg8
#LIBS += -L"/usr/local/lib/" -lgdcmcharls -lexpat -lgdcmzlib
This is an example converter, once you have the dicom image loaded, it will convert it to a Qt QImage.
bool imageConverters::convertToFormat_RGB888(gdcm::Image const & gimage, char *buffer, QImage* &imageQt)
{
unsigned int dimX;
unsigned int dimY;
int photoInterp;
const unsigned int* dimension = gimage.GetDimensions();
if (dimension == 0)
{
dimX = 800;
dimY = 600;
}
else
{
dimX = dimension[0];
dimY = dimension[1];
}
gimage.GetBuffer(buffer);
photoInterp = gimage.GetPhotometricInterpretation();
qDebug() << "photo interp = " << photoInterp;
qDebug() << "pixel format = " << gimage.GetPixelFormat();
// Let's start with the easy case:
if( photoInterp == gdcm::PhotometricInterpretation::RGB )
{
if( gimage.GetPixelFormat() != gdcm::PixelFormat::UINT8 )
{
return false;
}
unsigned char *ubuffer = (unsigned char*)buffer;
// QImage::Format_RGB888 13 The image is stored using a 24-bit RGB format (8-8-8).Format_RGB888 Format_ARGB32
imageQt = new QImage((unsigned char *)ubuffer, dimX, dimY, 3*dimX, QImage::Format_RGB888);
//imageQt = &imageQt->rgbSwapped();
}
else
if( photoInterp == gdcm::PhotometricInterpretation::MONOCHROME2 ||
photoInterp == gdcm::PhotometricInterpretation::MONOCHROME1
)
{
if( gimage.GetPixelFormat() == gdcm::PixelFormat::UINT8 || gimage.GetPixelFormat() == gdcm::PixelFormat::INT8
|| gimage.GetPixelFormat() == gdcm::PixelFormat::UINT16)
{
// We need to copy each individual 8bits into R / G and B:
unsigned char *ubuffer = new unsigned char[dimX*dimY*3];
unsigned char *pubuffer = ubuffer;
for(unsigned int i = 0; i < dimX*dimY; i++)
{
*pubuffer++ = *buffer;
*pubuffer++ = *buffer;
*pubuffer++ = *buffer++;
}
imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888);
}
else
if( gimage.GetPixelFormat() == gdcm::PixelFormat::INT16 )
{
// We need to copy each individual 16bits into R / G and B (truncate value)
short *buffer16 = (short*)buffer;
unsigned char *ubuffer = new unsigned char[dimX*dimY*3];
unsigned char *pubuffer = ubuffer;
for(unsigned int i = 0; i < dimX*dimY; i++)
{
// Scalar Range of gdcmData/012345.002.050.dcm is [0,192], we could simply do:
// *pubuffer++ = *buffer16;
// *pubuffer++ = *buffer16;
// *pubuffer++ = *buffer16;
// instead do it right:
*pubuffer++ = (unsigned char)std::min(255, (32768 + *buffer16) / 255);
*pubuffer++ = (unsigned char)std::min(255, (32768 + *buffer16) / 255);
*pubuffer++ = (unsigned char)std::min(255, (32768 + *buffer16) / 255);
buffer16++;
}
imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888);
}
else
{
std::cerr << "Pixel Format is: " << gimage.GetPixelFormat() << std::endl;
return false;
}
}
else
{
std::cerr << "Unhandled PhotometricInterpretation: " << gimage.GetPhotometricInterpretation() << std::endl;
return false;
}
return true;
}
#john elemans
If I use the code that you gave me, It seems to be worng. My image's pixel format is UINT16, so the program will execute the following sentences.
unsigned char *ubuffer = new unsigned char[dimX*dimY*3];
unsigned char *pubuffer = ubuffer;
for(unsigned int i = 0; i < dimX*dimY; i++)
{
*pubuffer++ = *buffer;
*pubuffer++ = *buffer;
*pubuffer++ = *buffer++;
}
imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888);
But after the converting, the result is not right.
The original image is like this:before
And this is the image which has been converted:after
The result proves that the code isn't right. I also have tried other ways. One of the codes that I have tried is this:
short *buffer16 = (short*)buffer;
unsigned char *ubuffer = new unsigned char[dimX*dimY*3];
unsigned char *pubuffer = ubuffer;
for (unsigned int i = 0; i < dimX*dimY; i++)
{
*pubuffer++ = *buffer16;
*pubuffer++ = *buffer16;
*pubuffer++ = *buffer16;
buffer16++;
}
imageQt = new QImage(ubuffer, dimX, dimY, QImage::Format_RGB888);
After I used this code to convert the image, I almost believed that I have succeeded. But the result is like this: sorry, I don't have the enough reputation the post more than 2 links.
I only want to convert DICOM image to bitmap, but I don't know how.
At last, thank you for your help.

Import FBX Vertex And Index Buffer To DirectX 11

Ok, I'm still trying to figure out how to correctly import FBX vertex and index buffer into DirectX 11. I wrote a controller for doing that and passing the vertex and index buffer to the DX11 renderer, the output should look like a cube but it is not, I only see triangles that don't make sense.
The code is shown below. I did multiply the Z values by -1, though.
What do I need to modify to get the render right?
#pragma once
#include "Array.h"
#include "Vector.h"
#include "fbxsdk.h"
#include <assert.h>
#include "constants.h"
class FbxController
{
public:
FbxController();
~FbxController();
void Import(const char* lFilename)
{
lImporter = FbxImporter::Create(lSdkManager, "");
bool lImportStatus = lImporter->Initialize(lFilename, -1, lSdkManager->GetIOSettings());
if (!lImportStatus) {
printf("Call to FbxImporter::Initialize() failed.\n");
printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString());
exit(-1);
}
lScene = FbxScene::Create(lSdkManager, "myScene");
lImporter->Import(lScene);
FbxNode* lRootNode = lScene->GetRootNode();
int childCount = lRootNode->GetChildCount();
FbxNode *node1 = lRootNode->GetChild(0);
const char* nodeName1 = node1->GetName();
fbxsdk::FbxMesh *mesh = node1->GetMesh();
int cpCount1 = mesh->GetControlPointsCount();
fbxsdk::FbxVector4 *controlPoints = mesh->GetControlPoints();
for (int i = 0; i < cpCount1; i++)
{
fbxsdk::FbxVector4 cpitem = controlPoints[i];
printf("%d, %d, %d, %d", cpitem[0], cpitem[1], cpitem[2], cpitem[3] );
VERTEXPOSCOLOR vpc;
vpc.Color.x = 0.5f;
vpc.Color.y = 0.5f;
vpc.Color.z = 0.5f;
vpc.Position.x = cpitem[0];
vpc.Position.y = cpitem[1];
vpc.Position.z = cpitem[2] * -1.0f;
m_vertices.add(vpc);
}
int pvCount = mesh->GetPolygonVertexCount();
int polyCount = mesh->GetPolygonCount();
for (int i = 0; i < polyCount; i++)
{
int polyItemSize = mesh->GetPolygonSize(i);
assert(polyItemSize == 3);
for (int j = 0; j < polyItemSize; j++)
{
int cpIndex = mesh->GetPolygonVertex(i, j);
m_indices.add(cpIndex);
float x = controlPoints[cpIndex].mData[0];
float y = controlPoints[cpIndex].mData[1];
float z = controlPoints[cpIndex].mData[2];
}
}
fbxsdk::FbxMesh *mesh2;
bool isT = mesh->IsTriangleMesh();
FbxNode *node2 = lRootNode->GetChild(1);
FbxNode *node3 = lRootNode->GetChild(2);
//lImporter->Destroy();
}
Array<VERTEXPOSCOLOR> GetVertexPosColors()
{
return m_vertices;
}
Array<unsigned int> getIndexBuffer()
{
return m_indices;
}
protected:
FbxManager *lSdkManager;
FbxIOSettings *ios;
FbxImporter *lImporter;
bool lImportStatu;
FbxScene *lScene;
private:
Array<VERTEXPOSCOLOR> m_vertices;
Array<unsigned int> m_indices;
};
I think you have some problems in your index buffer creation.
You simply gives an index for each vertex, and index buffer not working that way.
let me know if you solve this.

How to convert guid to *char

I would like to convert a CLSID to a *char in c++ so I can display it in a text box. I am new to c++ so please make this as simple a s possible.
Thanks
C'ish solution:
/* 128 bit GUID to human-readable string */
char * guid_to_str(const GUID * id, char * out) {
int i;
char * ret = out;
out += sprintf(out, "%.8lX-%.4hX-%.4hX-", id->Data1, id->Data2, id->Data3);
for (i = 0; i < sizeof(id->Data4); ++i) {
out += sprintf(out, "%.2hhX", id->Data4[i]);
if (i == 1) *(out++) = '-';
}
return ret;
}
This assumes the output buffer has been already allocated, and should be of a size of 37 bytes (including the null terminating character).
The output is of the form "75B22630-668E-11CF-A6D9-00AA0062CE6C"
Usage example:
GUID g;
char buffer[37];
std::cout << guid_to_str(&g, buffer);
Note:
This code exists because I had to implement GUID parsing under Linux, otherwise I would have used the Windows API function StringFromCLSID mentioned by #krowe.
Here is a great example for converting GUID to string and vice versa that I am using in my projects:
std::string guidToString(GUID guid) {
std::array<char,40> output;
snprintf(output.data(), output.size(), "{%08X-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X}", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
return std::string(output.data());
}
GUID stringToGUID(const std::string& guid) {
GUID output;
const auto ret = sscanf(guid.c_str(), "{%8X-%4hX-%4hX-%2hX%2hX-%2hX%2hX%2hX%2hX%2hX%2hX}", &output.Data1, &output.Data2, &output.Data3, &output.Data4[0], &output.Data4[1], &output.Data4[2], &output.Data4[3], &output.Data4[4], &output.Data4[5], &output.Data4[6], &output.Data4[7]);
if (ret != 11)
throw std::logic_error("Unvalid GUID, format should be {00000000-0000-0000-0000-000000000000}");
return output;
}
In the example, it firsts uses char* before converting to string so this is exactly what you are looking for in an efficient way.
The Windows API has a function for this:
CLSID clsid;
HRESULT hr = CLSIDFromProgID ((OLESTR "Adobe.SVGCtl.3"),&clsid);
// Get class id as string
LPOLESTR className;
hr = StringFromCLSID(clsid, &className);
// convert to CString
CString c = (char *) (_bstr_t) className;
// then release the memory used by the class name
CoTaskMemFree(className);
// Now c is ready to use
A CLSID is the same as a UUID, so you can use the UuidToString() function
http://msdn.microsoft.com/en-us/library/windows/desktop/aa379352(v=vs.85).aspx

Convert char to TCHAR* argv[]

How can I input text into TCHAR* argv[]?
OR: How can I convert from char to TCHAR* argv[]?
char randcount[] = "Hello world";
TCHAR* argv[];
argv = convert(randcount);
One way to do is:
char a[] = "Hello world";
USES_CONVERSION;
TCHAR* b = A2T(a);
/*This code did TCHAR in my project without A2T or any other converters. Char text is a some kind of array. So we can take letters one by one and put them to TCHAR. */
#include <iostream>
TCHAR* Converter(char* cha)
{
int aa = strlen(cha);
TCHAR* tmp = new TCHAR[aa+1];
for(int i = 0; i< aa+1; i++)
{
tmp[i]=cha[i];
}
return tmp;
}
int main()
{
char* chstr= new char[100];
chstr = "char string";
TCHAR* Tstr = new TCHAR[100];
//Below function "Converter" will do it
Tstr = Converter(chstr);
std::cout<<chstr<<std::endl;
std::wcout<<Tstr<<std::endl;
}

visual c++: convert int into string pointer

how to convert integer into string pointer in visual c++?
Use stringstream
#include <sstream>
stringstream ss;
ss << i;
string s = ss.str();
If you using CString, then you can use Format() method like this:
int val = 489;
CString s;
s.Format("%d", val);
search for atoi / itoa in your favorite documentation. Or try Boost (www.boost.org - library Conversion, lexical_cast).
Both ways are portable across different compilers.
There is a very easy method
int i=4;
String ^ s = Convert::ToString(i);
If you want a textual representation of the pointer address use sprintf.
If you want to treat the numeric value as a pointer to a string use casting like so:
int intValue = ...;
char * charPtr = (char*)intValue;
Take any C and C++ textbook. This simple C code should work in Visual C++ and others C++ compilels and convert 489 into "489":
char result[100];
int num = 489;
sprintf(result, "%d", num);
basic C++
char text[100];
int num=123;
itoa(num,text,10);
This is how I did it in my homework since we were only allowed to use some predetermined libraries. I'm pretty sure it's not considered a "best practice" though ;)
string int2string(int integer) {
string str;
int division = integer;
while (division > 0) {
str = char('0' + (division % 10)) + str;
division = division / 10;
}
return str;
}
I think the easiest one would be:
int i;
String s=i.toString();
// It is about Visual C++
You got homework? a generic one, tested if g++, http://effocore.googlecode.com/svn/trunk/devel/effo/codebase/addons/inl/include/impl/algo_impl.h
:
#ifdef __cplusplus
static inline char *int2a_put(uintptr_t i, char *s)
{
do {
*s++ = '0' + i % 10;
i /= 10;
} while (i);
return s;
}
static inline void int2a_reverse(char *head, char *tail)
{
for (*tail = '\0'; --tail > head; ++head) {
/* exchange */
(*head) ^= (*tail);
(*tail) ^= (*head);
(*head) ^= (*tail);
}
}
template<typename t>
static inline const char *int2a(t i, char *s)
{
char *p;
char *ret = s;
bool f = false;
p = s;
if (i < 0) {
*p++ = '-';
++ s;
/*
* In limits.h, INT_MAX was defined as
* maximum values a `signed int' can hold.
* and LONG_MAX was defined as maximum values
* a `signed long int' can hold.
*/
switch (sizeof(t)) {
case 8:
{
/*
* Inject \p a to prevent from complaint
* of compiler.
*/
ef64_t a = (ef64_t)i;
if (-LLONG_MAX > a) {
i = (t)LLONG_MAX;
f = true;
}
}
break;
case 4:
case 2:
case 1:
{
/*
* Inject \p a to prevent from complaint
* of compiler.
*/
int a = (int)i;
if (-INT_MAX > a) {
i = (t)INT_MAX;
f = true;
}
}
break;
default:
break;
}
if (!f) {
i = -i;
}
}
p = int2a_put((uintptr_t)i, p);
if (f) {
++ *s;
}
int2a_reverse(s, p);
return ret;
}
/*
* No "static" otherwise g++ complains
* "explicit template specialization cannot have a storage class"
*/
template<>
/*static*/ inline
const char *int2a<uintptr_t>(uintptr_t i, char *s)
{
char *p = int2a_put(i, s);
int2a_reverse(s, p);
return s;
}
#else

Resources