473,406 Members | 2,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

accessing VC++ unmanaged long from managed code

I'm having trouble accessing an unmanaged long from a managed class in
VC++.NET

When I do, the contents of the variable seem to be mangled. If I
access the same variable byte-by-byte, I get the correct value.
Regardless what I set the variable to, the value that is returned for a
long is always the same value. What's going on...can anyone help me?

A short version of the code follows:

//HEADER
namespace MyProgram
{

#pragma unmanaged
__nogc class unmanagedClass
{
public:unmanagedClass(); //CONSTRUCTOR

public: union{
struct {
long unmanagedLong; //UNMANAGED VARIABLE
} myData;
struct {
char bytes[4];
} b_myData;
} myUnion;
};
#pragma managed
public __gc class managedClass
{
public:managedClass(); //CONSTRUCTOR
private: unmanagedClass __nogc *ptrUnmanagedClass; //PTR TO UNMANAGED
CLASS
public:System::String* Get_unmanagedLong(); //METHOD TO GET
UNMANAGED VARIAHBLE
};
}

//CPP LISTING

//CONSTRUCTORS
MyProgram::unmanagedClass::unmanagedClass(){
unmanagedLong=1536; //HEX #0600
}
MyProgram::managedClass::managedClass(){
ptrUnmanagedClass=new unmanagedClass();
}
System::String* MyProgram::managedClass::Get_unmanagedLong(){
System::String *result;

//NEXT RETURNS CORRECT VALUE OF #0600
result=System::String::Concat(

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[0])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[1])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[2])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[3])));

//NEXT RETURNS INCORRECT VALUE OF #73CB6A62
result=System::String::Format("{0:x}",__box(ptrUnm anagedClass->myUnion.myData.unmanagedLong));

return(result);
}

Sep 12 '06 #1
5 2372
Andy wrote:
I'm having trouble accessing an unmanaged long from a managed class in
VC++.NET

When I do, the contents of the variable seem to be mangled. If I
access the same variable byte-by-byte, I get the correct value.
Regardless what I set the variable to, the value that is returned for a
long is always the same value. What's going on...can anyone help me?

A short version of the code follows:

//HEADER
namespace MyProgram
{

#pragma unmanaged
__nogc class unmanagedClass
{
public:unmanagedClass(); //CONSTRUCTOR

public: union{
struct {
long unmanagedLong; //UNMANAGED VARIABLE
} myData;
struct {
char bytes[4];
} b_myData;
} myUnion;
};
#pragma managed
public __gc class managedClass
{
public:managedClass(); //CONSTRUCTOR
private: unmanagedClass __nogc *ptrUnmanagedClass; //PTR TO UNMANAGED
CLASS
public:System::String* Get_unmanagedLong(); //METHOD TO GET
UNMANAGED VARIAHBLE
};
}

//CPP LISTING

//CONSTRUCTORS
MyProgram::unmanagedClass::unmanagedClass(){
unmanagedLong=1536; //HEX #0600
}
MyProgram::managedClass::managedClass(){
ptrUnmanagedClass=new unmanagedClass();
}
System::String* MyProgram::managedClass::Get_unmanagedLong(){
System::String *result;

//NEXT RETURNS CORRECT VALUE OF #0600
result=System::String::Concat(

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[0])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[1])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[2])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[3])));

//NEXT RETURNS INCORRECT VALUE OF #73CB6A62
result=System::String::Format("{0:x}",__box(ptrUnm anagedClass->myUnion.myData.unmanagedLong));

return(result);
}
Did not reproduce your problem in VC8.0

// VC8.0 Common Language Runtime Support, Old Syntax (/clr:oldSyntax)

#include "stdafx.h"

using namespace System;

#pragma unmanaged
__nogc class unmanagedClass
{
public:unmanagedClass()
{
myUnion.myData.unmanagedLong=1536; //HEX #0600
}

public: union{
struct {
long unmanagedLong; //UNMANAGED VARIABLE
} myData;
struct {
char bytes[4];
} b_myData;
} myUnion;
};
#pragma managed
public __gc class managedClass
{
public:managedClass()
{
ptrUnmanagedClass=new unmanagedClass();
}//CONSTRUCTOR
private: unmanagedClass __nogc *ptrUnmanagedClass; //PTR TO UNMANAGED CLASS
public:System::String* Get_unmanagedLong()
{
System::String *result;

//NEXT RETURNS CORRECT VALUE OF #0600
String* result1=System::String::Concat(

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[0])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[1])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[2])),

System::String::Format("{0:x}",__box(ptrUnmanagedC lass->myUnion.b_myData.bytes[3])));
//NEXT RETURNS INCORRECT VALUE OF #73CB6A62
String* result2
=System::String::Format("{0:x}",__box(ptrUnmanaged Class->myUnion.myData.unmanagedLong));
result = new String(",");
result = result->Concat(result1,result);
result = result->Concat(result,result2);
return(result);
}
//METHOD TO GET UNMANAGED VARIAHBLE
};

int main()
{
Console::WriteLine(L"access unmanaged from managed");
managedClass* m = new managedClass;
Console::WriteLine(m->Get_unmanagedLong());
return 0;
}
Sep 13 '06 #2
hmmmm.....

Perhaps I should provide the context in which this unmanaged/managed
variable reading is being applied.

I am trying to read an MS Word 2003 document from Visual BASIC.NET 1.1,
and I don't want to use office automation to do this. The process
should work regardless if MS Word is available or not.

MSWord documents use Microsoft's structured storage API for their
read/write operations, which was written before .NET ever existed as
C++ unmanaged code (Structured storage is a file format Microsoft
developed for OLE2 that treats a file as a virtual mini-disk drive).

The Structured Storage API makes heavy use of pre-defined C++
structures, so it cannot be directly used from Visual Basic. And,
because you have to supply variables to hold the results of the calls
to the structured storage API (the MSWord FIB, structured storage
directories, etc), your program holding these variables must also be
written in unmanaged code as well.

A solution to this is to write a callable VC.NET .dll that can "wrap"
the structured storage API and pass/convert the values between the
Visual Basic program and the API itself.

The Visual C++ wrapper needs to have both an unmanaged (to hold
variables used by the sturctured storage API) and managed (for calls to
the structured storage API and conversion of values to standardized
System:: typedefs) sections.

In the MSWord FIB (this is a kind of header record in an MSWord
document that describes the contents of the document; its comparible to
a directory), there is a field called fcMin. This field contains the
offset in bytes of where the ascii text of the document begins (text is
kept separate from its formating inside of MSWord files).

fcMin is defined as a long (4 bytes). When I read the contents of
fcMin in Visual Basic, I get a non-sensical result of an offset
pointing beyond the size of the document file itself. But, if I
inspect the contents of this field byte-by-byte, I find a different
value which I have verified to be the accurate offset to the beginning
of the text in the document.

When I read the field from VC++ managed code, I get the correct value.
But, as soon as I equate it to a System::Int32, I get the wrong value.
I assumed that I get the wrong value in VC++, however, I am actually
inspecting the contents of the field from Visual Basic by calling my
wrapper's get method for this field (I capture the returned value in a
Visual Basic System::Int32 variable). This problem doesn't happen if I
read the field inside of VC++ byte-by-byte, concatenate the byte values
and return a System::String. In this case, the correct value appears
in both the VC wrapper and the calling VB program.

I don't think this problem is caused by the value crossing boundaries
between VC++ to VB because I am using the .NET standardized system
typedefs which are supposed to be treated the same regardless of what
language they are used in. And, the fact that the byte-by-byte value
doesn't get distorted when it is passed supports this.

There must be some problem in setting a System::Int32 value to a C++
long value in Visual C++. System::Int32 (and all other System::
typedefs) are actually wrappers for C++ primitives. I believe the
wrong value that I get (which doesn't change) is actually the value of
a pointer inside of the System::Int32 object, or that the System::Int32
object is not being correctly initialized or set when it is equated to
a C++ unmanaged long.

thanks for looking at my sample code,
Andy

Sep 13 '06 #3

After further testing, and borrowing your technique of combining
strings to simultaneously report on the same variable from different
views, I've determined that my field structure is off.

Reading the value by using byte offsets works because I am accessing
the correct location. But, reading the variable name for the same
memory area shows that the contents actually come from a location 12
bytes further into the structure.

Thanks for your help, Andy

Sep 13 '06 #4

"Andy" <an****@infotek-consulting.comwrote in message
news:11**********************@e63g2000cwd.googlegr oups.com...
>
After further testing, and borrowing your technique of combining
strings to simultaneously report on the same variable from different
views, I've determined that my field structure is off.

Reading the value by using byte offsets works because I am accessing
the correct location. But, reading the variable name for the same
memory area shows that the contents actually come from a location 12
bytes further into the structure.
#pragma pack
>
Thanks for your help, Andy

Sep 13 '06 #5
#pragma pack

Thanks for your suggestion. I've added #pragma pack() to my unmanaged
code as you have suggested.

For those reading this post in the future:

pragma pack is a MS VC++ compiler directive on how the compiler should
align structure fields on memory boundaries. Typically, multi-byte
fields such as longs and shorts have to begin on an even memory
address. If the compiler finds a field that doesn't do this, it shifts
it to the next available even address boundary; pack() cancels this
behavior.

The MSWord 97 file structure layout has a long field called lKey (which
contains an encryption key) that begins on an odd address boundary
because of a char defined before it. Without pragma pack, the compiler
will shift this field along with all the others that follow it up
several bytes. This impacts the value you get in fcMin because this
field is defined after lKey.

Other reasons you may not get the correct fcMin value are the two two
bit field structures doctype and savetype are being expanded to more
bytes than the spec perscribes by the compiler. Solution is to union
these structures with a field that is of the perscribed size to ensure
that this expansion doesn't occur.

Andy

Sep 14 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Weston Fryatt | last post by:
(Sorry for spamming multiple groups, But I need a solution to this problem) I think this should be a simple question on Memory Allocation in a managed DLL and passing a memory pointer over to an...
3
by: Francis Urquhart | last post by:
I am trying to find the simplest possible way of writing a GUI to run on top of a standard C++ library written in VC++. I would like to avoid MFCs, COM, and if possible .Net wrappers. The goal...
6
by: Ben Terry | last post by:
Hello, I have a VS 2003.NET solution which consists of four c++ unmanaged legacy projects. I am adding a new project to the solution which will be in c#. What do I need to do to my c++ projects...
1
by: Steve | last post by:
We are considering the ways to migrate our VC++ 6.0 applications to .NET platform. It would be nice to rewrite them completely in C#, but due to the time constraints this option is out of...
8
by: The unProfessional | last post by:
To the VC .Net'ers out there... I noticed alot of strange behavior in the way VC .Net apps behave in the IDE. It's a bit odd, so maybe people have workarounds. I'm worried to devote my project...
12
by: Maansi Sanghi | last post by:
Hi, Is there a way to use the System.Xml.Schema classes in VC++ 6.0? Regards, Maansi
1
by: vemulakiran | last post by:
Hi all, I have doubt regarding .NET. I have a tool which was developed on VC++ 6.0(Win32 Application ). The application communicates with library (API) which was developed on VC++ 6.0 called core...
3
by: Dave | last post by:
I've seen at least one article on this: How to access classes, etc. managed-to-unmanaged. I can't find it. Any tricks or pointers? I guess the class name won't get munged but I'm not clear about...
1
by: Matyi | last post by:
Hello everybody! I've this problem: I'm working on a download meter, based on wpcap. As wpcap code is unmanaged, I decided to create the needed functions in a unmanaged project (one for...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.