Reputation: 2246
I'm trying to get a pointer to a string
, where the pointer is of type int
. I'm not sure if I'm doing it correctly. I just found out yesterday about unsafe and fixed, so I'm still questioning this a bit. Can I just cast the char*
to int
? I'm not getting any errors, but the methods are not working, so I'm not sure if the pointer is wrong or if I'm doing something wrong with the 3rd party OCX (for which there's no support).
3rd Party Documentation for C++ calls:
BlobToVariant(VARIANT *pV, long BlobPointer)
WriteVToFile(VARIANT *pV)
What VS2010 C# Intellisense says:
BlobToVariant(ref object v, int BlobPointer)
WriteVToFile(ref object v)
Here is my code:
string imageBlob = "superlongstring";
// 3rd Party ActiveX control for tiff image files
TIFFLib.TIFF tiff = new TIFFLib.TIFF();
// Variant object that will hold image
object blobVariant = new object();
unsafe
{
fixed (char* p = imageBlob)
{
int blobPointer = (int)p;
tiff.BlobToVariant(ref blobVariant, blobPointer);
tiff.WriteVToFile(ref blobVariant);
}
}
Upvotes: 0
Views: 1742
Reputation: 169068
BlobToVariant
probably expects a pointer-to-C-string; a char*
. While char
is a 1-byte data type in C, it is a 2-byte data type in C#. A C# char*
and a C char*
are different, incompatible types.
You will need to first convert the string to a sequence of bytes, using whatever text encoding is appropriate. I will use UTF-8 here, but you should switch to something else if this function doesn't accept UTF-8 input.
// "using System.Text;" assumed.
byte[] imageBlobBytes = Encoding.UTF8.GetBytes(imageBlob);
Now you do the same thing as you were doing, only you use a byte*
, which corresponds to the char*
type in C. (To be precise, they may differ in signed-ness. The C# byte
type is unsigned, and the C char
type is commonly signed, but we don't really care about that here.)
// 3rd Party ActiveX control for tiff image files
TIFFLib.TIFF tiff = new TIFFLib.TIFF();
// Variant object that will hold image
object blobVariant = new object();
unsafe
{
fixed (byte* p = imageBlobBytes)
{
int blobPointer = (int)p;
tiff.BlobToVariant(ref blobVariant, blobPointer);
tiff.WriteVToFile(ref blobVariant);
}
}
Note that this will only work on a 32-bit host, or on a 64-bit host if the process is executed as 32-bit. The C# int
type is always 32 bits wide, while byte*
will be 32 bits wide in a 32-bit execution environment, and 64 bits wide in a 64-bit execution environment. If executed in a 64-bit environment, this code will truncate the pointer and the resulting behavior will be undefined.
Upvotes: 1