|
Hi!
I want to code a wrapper for an existing c++-class.
The class has a function to define a callback and
when I set the callback I can give it some data
for me on the way: A void*. I can use it to
store stuff I need when I'm inside the callback.
This should be a common c++-concept and I think
the best thing for the managed proxy-class I'm
writing is a delegate, so that the C#-users who
call the function can give it a delegate which
is then called by the callback-proxy.
So I store the two delegates inside a class:
<br />
__delegate void CallBackNewFile(String* fname,int size);<br />
__delegate void CallBackBytes(int size);<br />
<br />
__gc class ExtractInfo<br />
{<br />
public:<br />
CallBackNewFile* newfile;<br />
CallBackBytes* bytes;<br />
};<br />
Now I want to give the callback-function
a void*:
<br />
static bool Extract(String* cabfile,String* DestDir,bool DontMakeFolders,<br />
CallBackNewFile* newfile,CallBackBytes* bytes)<br />
{<br />
CCabExtractor cab;<br />
if (!cab.Create())<br />
return false;<br />
ExtractInfo __pin * inf=new ExtractInfo();<br />
inf->newfile=newfile;<br />
inf->bytes=bytes;<br />
cab.SetCallback(&mycallback,inf);<br />
<br />
Please notice the "ExtractInfo __pin * inf=new ExtractInfo();". Is
that the right way of pinning?
Converting the gc-pointer into a void* seems to work!
BTW:
The SetCallback function has this declaration:
<br />
void SetCallback (CALLBACKFUNC pCallback, void * pv)<br />
And now comes the problem:
My callbackfunction wants to do something with the passend void* pointer:
<br />
static bool __stdcall mycallback (void * pv, const char * lpszPath, DWORD cb)<br />
{<br />
ExtractInfo* i=(ExtractInfo*)(pv);<br />
if (lpszPath==NULL)<br />
{<br />
if (i->bytes)<br />
i->bytes(cb);<br />
} else {<br />
if (i->newfile)<br />
i->newfile(lpszPath,cb);<br />
}<br />
return true;<br />
}<br />
The problem is the line "ExtractInfo* i=(ExtractInfo*)(pv);
I can't get this line right so that it compiles!
I tried several variants. I think it won't let me get
a __gc class out of a void* pointer.
BUT: That class HAS to be a __gc class, otherwise
the compiler complained about declaring delegates inside
it.
Can someone help me?
How do I transport a managed pointer/reference THROUGH
unmanaged code?
How can I cast a void* into a reference to a managed
object?
Many thanks in advance!!!
|
|
|
|
|
You can pass a delegate to the callback. Please many here do not response to anonymous poster - there is nothing to hide anyway!
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Paul Selormey wrote:
You can pass a delegate to the callback. Please many here do not response to anonymous poster - there is nothing to hide anyway!
Thanks
Okay, I'm registered now. Strange that it's possible to post without registration...
What do you mean with "I can pass a delegate to the callback"?
My guess is that I can pass a delegate directly to the SetCallBack function.
This is interessting and might be a way to go, but does anybody know about
converting a void* into a reference to a managed object?
How to push .NET-stuff through existing c++-functions and APIs??
Many thanks in advance!
|
|
|
|
|
If you wish to pass native pointer like void* around, use the System::IntPtr. It has the constructor for void*.
System::IntPtr intPtr((void*)pv);
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
i got a basic .cpp file i use too be able too just compile it but in .net studio the compile buttons greyed out
how do i over come this?
|
|
|
|
|
Create an empty project console project and add your file to the project and compile it.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi there!
I have just started using managed c++ (until now I have always used "pure" C++), so I have a question that might sound stupid to you.
I want my class to have a string-member that descibes the class. This string is for example returned by ToString(). As a C++ I would want to make it static const to ensure it is only once in memory and cannot be altered. However, ToString() returns a non-const String. Do I have to copy the string all the time I call ToString()?
Maybe some code shows what I mean:
<br />
public __gc class Foo<br />
{<br />
public:<br />
System::String * ToString();<br />
private:<br />
static const System::String * ClassID = S"This is class Foo";<br />
};<br />
<br />
System::String * Foo::ToString()<br />
{<br />
<br />
<br />
return static_cast<System::String*>(const_cast<System::String*>(Foo::ClassID)->Clone());<br />
}<br />
Are there any other ways to avoid copying all the time?
Greetings
Andre (VizOne) Loker
|
|
|
|
|
Someone already gave me the clue. MSDN says: "String Class. Represents an immutable series of characters." Stupid me! RTFM...
- Andre
|
|
|
|
|
I tried to open a PE file with a program called PEExplorer .. Opend the header & discoverd that all the items in the header is correct..
but i found something strange i igot "the address of entry point" field from the header but when i checked that address i found it's so different from the contents that the PEExplorer program shows...
i found that the "image base" field is added some times 2 the address of the entry point field...
for example the address of entry point is: 0000E67Ch
& the image base is: 01000000h
but when i run the disassembler view of the PEExplorer i find that the address of the entry point is 0100E67Ch & this address can't be located coz the file size is smaller than it & the contents that the disassembler show in this location 0100E67Ch i can find it in another different place in my file
plz does any one knows how is this operation handled & how can i reach 2 the real entry point of an exe file...
my email is
blacksun_damn@yahoo.com,
ashshab_beh@yahoo.com
my best regards ... & thanx alot 4 reading
blacksun
|
|
|
|
|
Hi all!
Is there an easy way (maybe I'm just blind?) to convert between unmanaged byte arrays and managed Byte arrays??
Cheers
TIA
Martin
"Situation normal - all fu***d up"
Illuminatus!
|
|
|
|
|
Have you examined Marshall::Copy() method?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Nope! But looks interesting for one way of the conversion!
Thanks
Martin
"Situation normal - all fu***d up"
Illuminatus!
|
|
|
|
|
Yes, try it. Remember to take a look at ReadByte method too. In fact the Marshall class is all you need - good luck.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello All,
What is the MC++ version of the "Optimizing Event Implementation"
described in the MSDN?
The C# version was implemented as:
-----------------------------------------------------------------
private static readonly object ClickEvent = new object();
public event EventHandler Click
{
add
{
Events.AddHandler(ClickEvent, value);
}
remove
{
Events.RemoveHandler(ClickEvent, value);
}
}
protected virtual void OnClick(EventArgs e)
{
EventHandler clickEventDelegate = (EventHandler)Events[ClickEvent];
if (clickEventDelegate != null) {
clickEventDelegate(this, e);
}
}
-----------------------------------------------------------------------
Frankly, is there no MC++ programmer on the MSDN documentation team?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello Paul,
This stuff sure is in dark, poorly-charted waters! It wasn't easy to find, but this seems to be the MC++ translation:
private:
static Object *ClickEvent = new Object();
public:
__event void add_Click(EventHandler *pEH)
{
get_Events()->AddHandler(ClickEvent, pEH);
}
__event void remove_Click(EventHandler *pEH)
{
get_Events()->RemoveHandler(ClickEvent, pEH);
}
protected:
virtual void onclick(EventArgs *e)
{
EventHandler *clickEventDelegate = (EventHandler*)( get_Events()->get_Item(ClickEvent) );
if (clickEventDelegate != null) {
clickEventDelegate(this, e);
}
}
However, I am unsure about how to properly declare ClickEvent , since I cannot find an equivalent to C#'s readonly . Most of this stuff I found in MSDN under the "Managed Extensions for C++ Specification", section "10 Events" ("ms-help://MS.VSCC/MS.MSDNVS/vcmxspec/html/vcManagedExtensionsSpec_10.htm"), and pages on __event and __delegate . MC++ is not exactly well documented!
You are one of the few people on this site who seem interested in delving deeper into MC++. Part of it is probably due to so little attention in documenting MC++ like C# is, as you mentioned. I sure hope this gets more coverage after VS.NET 2003 is released (HINT, HINT, any VS.NET team people out there)...
Cheers
|
|
|
|
|
Hello Jeff,
I know you will be here
Thanks for the support. I am working on MC++ product and do not think C# could cut it.
I have posted the same to the VC.NET news group where there are so many [MSFT] figures but no one is picking the call
Jeff J wrote:
However, I am unsure about how to properly declare ClickEvent, since I cannot find an equivalent to C#'s readonly
This is my problem too. The translation as you coded seems to favor having the event as "User-defined Event Accessor methods", where the user codes the actual event accessors instead of the compiler generation (i.e. the user writes the add_, remove_, and raise_ methods).
I do not know if the raise_ method is required here and could not find any MC++ sample to confirm my thoughts.
I think I have to simply test the above and go with it.
Again, thanks for the support.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I'm updating some old VC++ code to .NET C++ to talk to a serial device. I cannot get the VC++ code to compile correctly under a managed C++ app. i'm new to the mc++. is this the unmanaged c++ i read about or something else im doing wrong. any help would be great.
megadith@hotmail.com
|
|
|
|
|
Hi all.
Please help to me to disassemble a problem of a call Win32 of functions from unmanaged С++.
You see they are visible in the field of global names.
How to call the ::MessageBox ?
Whether it is possible basically ?
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
#include "iostream.h"
#include "stdio.h"
typedef void * HWND;
#pragma unmanaged
__nogc class UnmanagedClass {
public:
static void metod (void)
{
// ::MessageBox(0," Message_from_Win32 ", " Unmaneged_C++ ", 0);
}
};
[DllImport ("user32")]
extern "C" int MessageBoxA(HWND hWnd, String *pText, String * pCaption,unsigned int uType);
#pragma managed
void main(void)
{
printf (" Message_from_standart_C \n\r");
cout << " Message_from_standart_C++ " << endl;
Console::WriteLine (" Message_from_NET ");
MessageBoxA (0," Message_from_Win32 ", " PInvoke ", 0);
UnmanagedClass::metod();
}
|
|
|
|
|
You do not need to wrap MessageBox (or any other API call) with DllImport marshaling in MC++, unless you need to make it visible to other .Net languages (or other MC++ code). Unmanaged C++ can call API stuff as usual.
However, here is a version of MessageBox I have tried successfully with both MC++ and C#:
[DllImport("user32.dll", CharSet=Auto)]
int<br />
MessageBox(IntPtr hWnd, String *pText, String *pCaption, unsigned uType);
I believe you can use HWND as you defined it within MC++, though I am not sure how other .Net classes would feel about it. An IntPtr is a managed version of void* anyway, so that's what I used. The extern "C" bit is not necessary, and might not even be allowed. I have always used DllImports within a namespace, not globally, but I have used them both within and outside of class definitions.
Cheers
|
|
|
|
|
I am trying to access a simple C++ class and method from c#. My code goes something like this:
mMath.cpp:
#using <mscorlib.dll>
using namespace System::Runtime::InteropServices;
mMath::mMath(){
m_pOperator = new Operator();
}
int mMath::mAdd(int iIn1, int iIn2){
int mAns = m_pOperator->Add(iIn1, iIn2);
return mAns;
}
mMath.h:
#include "Operator.h"
using namespace System;
public __gc class mMath: public IDisposable{
Operator __nogc* m_pOperator;
public:
mMath();
~mMath();
//and an mMath dispose method
int mAdd(int i1, int i2);
};
Operator.cpp:
#include "stdafx.h"
#include <string.h>
#include "mMath.h"
#include "Operator.h"
Operator::Operator(void){}
int Operator::Add(int in1, int in2){
int ans = (in1 + in2);
return ans;
}
and Operator.h:
#pragma once
__nogc
class Operator{
public:
Operator();
int Add(int in1, int in2);
};
Created the C++ code in Visual Studio as an Extended Stored Procedure project. Compiled the C++ code into a .dll and referenced it in my C# Smart Device Application Project. When I try to run it in the emulator it won't create an instance of the mMath object:
c# code:
mMath mm = new mMath();
I get a System.TypeLoadException with message TypeLoadException.
All help will be greatly appreciated... I've tried to follow sample tutorials but I've run out of resources! Thanks!
pj
|
|
|
|
|
I am not sure about what is causing your TypeLoadException, but did you try testing your classes within the same MC++ project? That is, seeing if the classes run in a plain MC++ console project without putting them into a DLL. That might provide some clues.
Incidentally, .Net destructors should be declared protected, and not public as is common in straight C++. The idea is to hide the destructor and promote calling the Dispose method, which can call the destructor if necessary. The CLR interprets a destructor as as the "Finalize" method formally used in .Net, although I doubt it's causing your problem.
Cheers
|
|
|
|
|
What means for visual designing of the forms in maneged C ++ are ?
Or it can be made only by means of a code ?
|
|
|
|
|
Right now, there is no GUI (visual) designer for managed C++. However, VS.Net 2003 will have one, and last I heard, is due to be released in February.
Cheers
|
|
|
|
|
I read in one article that there is a integrited Crystal Report in VC.NET
is that true, if yes could anybody tell me how to use that(a simple example).
thanx.
|
|
|
|
|
Hello All,
I am getting frustrated now....
How do I store cursors and retrive them from a .NET assembly dll?
The resource file support does not seems to extend to cursors. I am
building components not an application and wish to add several cursors
to the component or resource only dll.
Any help?
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|