|
Okay, now that I've gotten past my first hurdle I am facing a little more complex problem -- how can I map handles to managed objects? I have a callback entry point and would like to retrieve an existing instance of a managed class to deal with the callback, based on the handle that the function gets as a parameter. But I can't have a global map from handle to class *, because .NET forbids non-managed classes from storing pointers to managed classes; and managed classes can't have non-local linkage. What do I do? There's got to be some way of doing it -- picture going from your WndProc to a window object.
My desired sequence of events is: object is created by a managed client. Object then registers a callback with the API and gets back a handle. Callback enters, sees handle and passes it to a lookup function which retrieves the object. Object deals with callback and returns. etc.
Can I have a map from handle to class * as a static member of the managed class? Something tells me I cannot...
|
|
|
|
|
I have come up with a stop-gap solution but it is quite inelegant and defeats the purpose, somewhat, of managed classes. It is this:
__gc class MyClass
{
static MyClass *instances;
MyClass *next;
public:
MyClass(): next(instances) { instances = this; }
MyClass *Lookup(HANDLE h) { /*iterate thru linked list til you find it */ }
}
When the callback enters it can call MyClass::Lookup and then use the returned instance to deal with the callback. *But* MyClass instances will never be deleted (if my understanding of __gc is correct) -- I have to add a Shutdown() function to remove the instance from the list -- and call this function just before the last referance to the instance goes out of scope.
What I want is a way to declare non-__gc pointers to managed type objects -- then the destructor of a MyClass would be called when the last __gc reference to it went out of scope, and the destructor could then be responsible for cleaning up the instances list and deregistering the callback. But it seems like there is no way to do this.
Maybe what I should do, is make MyClass be non-managed but give it a managed wrapper class. Then I think I can do exactly what I want. I will give this a try and report back.
READIN writin and rhythmetic
|
|
|
|
|
Hi,
When i am trying to create a new form which is derived from some other form it is giving me design time problems. ie., When i am creating a new form , i can design the form according to my needs. but if i am making it derived from other form. at run time it is working fine. but i am unable to see the form at design time. so, please tell me how can i create a form which is derived from some other base form.
|
|
|
|
|
Visual Inheretance isn't currently supported by the VC++ Windows Forms designer. As you've discovered the code compiles/runs fine, but the designer itself won't support this.
Nick Hodapp
This posting is provided “AS IS” with no warranties, and confers no rights. You assume all risk for your use. © 2003 Microsoft Corporation. All rights reserved.
|
|
|
|
|
I'm pretty new to managed C++ -- hopefully this is something easy to do. I want to call windows API functions from within the module where my managed class is defined. But when I write #include <windows.h>, I get this compiler error: "assembly access specifier modified from 'public'", on the line ine ServProv.h where IServiceProvider is declared, followed by a few more errors and then a compilation aborted. What should I be including instead of <windows.h>?
Thanks!
|
|
|
|
|
I have to define WIN32_LEAN_AND_MEAN before including windows headers. Thanks for your time anyways!
|
|
|
|
|
|
Thanks, I thought of doing that but wasn't sure whether that would work -- I thought it would confuse the linker -- guess I was wrong. I'll keep that in mind in case I need some non-LEAN_AND_MEAN functionality.
|
|
|
|
|
Hi,
I am trying to generate a .h file from an idl file.
For this I am using Microsoft's MIDL Compiler.
I gave the following command:
midl myIDl.idl /h myidl.h
But when I run the command line exe, it gives me an error message saying:
midl : command line error MIDL1001 : cannot open input file oaidl.idl
can ne1 help
thanks
simon
|
|
|
|
|
Is your paths setup correctly?
<a TITLE="See my user info" href=http:
|
|
|
|
|
i want to move mouse in c++ by seeting coordinates value in registers
like
a.h.dx=50
etc
i want to use it in demo
plz reply me with some code examples
|
|
|
|
|
I am running into some probems using the shared assembly. I seem to be able
to check it into the GAC, but I do not seem to able to find the file when I
reference it. I think I have done everything the help files say to do, but
when I go to build it, I get file not found error. This code works when the
assembly is private. I put a detailed explaination of problem with screen
shots and source code on the web at
http://www.robertpeterson.ws/screenshots/GACproblem.htm
Sorry for using large image sizes. I suspect that there may be some compiler
option that I haven't set, but I can't imagine what else I should change. I
will continue to research and hopefully correct the problem, but I hope you
will look at the web page and let me know if you have any suggestions. I have
looked at 4 books on Visual C++.NET. They all say how to make an assembly
shared, but they don't say how to include it into a program (at least I
haven't noticed an example yet.) The other thing I noticed is that they all
show c://winnt/assembly as the example, but not C://WINDOWS/assembly where the
gacutil puts it on the XP box.
#include "stdafx.h"
#using <mscorlib.dll>
#using <reformaterclasslibrary.dll> // File that is in the GAC
#include <iostream.h>
#include <tchar.h>
using namespace ReformaterClassLibrary;
using namespace System;
// This is the entry point for this application
int _tmain(void)
{
ParagraphReader * pReader = new ParagraphReader();
// Read the contents of the file
pReader->FilePath = "a://paragraph.txt";
pReader->Read();
// Instantiate a Paragraph Rewriter class;
ParagraphRewriter * pRewriter = new ParagraphRewriter(pReader->Data);
pRewriter->MakeTriangle2(); // Reformat the paragraph
// Instantiate a Paragraph Writer object to write the data to a disk
ParagraphWriter * pWriter = new ParagraphWriter("a://triangle.txt");
pWriter->WriteParagraph(pRewriter->Output);
cout << "System terminated normally." << endl;
return 0;
}
|
|
|
|
|
To my knowledge, none of the .NET compilers will compile with a reference to an assembly in the GAC, instead you need to reference an absolute location. When you run your program the framework will look in the GAC first for the assembly before it starts looking in the private directories.
James
"I despise the city and much prefer being where a traffic jam means a line-up at McDonald's"
Me when telling a friend why I wouldn't want to live with him
|
|
|
|
|
Perhaps your right. That would explain why I can't seem to do it. However, this raises two new questions. 1) How do I reference the absolute location programmatically or in visual studio.Net? 2) How can I compile code that uses classes in the assembly in the GAC? If I can't reference it at compile time I just get a bunch of undeclared identifier and namespace not found errors.
|
|
|
|
|
SuperGeek wrote:
1) How do I reference the absolute location programmatically or in visual studio.Net?
In your #using statement you should be able to give the full path, or you can add the directory containing your assembly to the #using search path (in the project's properties go to C/C++ -> General and it should be right at the top.
SuperGeek wrote:
How can I compile code that uses classes in the assembly in the GAC?
The assemblies should also exist somewhere else on your system; if they don't the vendor screwed up (IMHO). For instance, in C#/VB.NET the Add Reference dialog doesn't pull its assembly list from the GAC, instead there are is a key in the registry where vendors can add values. This key lists all of the places the Add Reference dialog should look for assemblies.
That key could give you an idea of where to search to find the assemblies.
HTH,
James
"I despise the city and much prefer being where a traffic jam means a line-up at McDonald's"
Me when telling a friend why I wouldn't want to live with him
|
|
|
|
|
Ok, I compiled it by setting the search path to the assembly that I signed and checked into the GAC with sn.exe and gacutil.exe. I can see that the assembly is in the gac. However, when move the .exe that I just built to say the desktop, and try to run it, I get a runtime error. System.IO.FileNotFound error. I presume it is not really finding the dll in the GAC. Does it look in the GAC at runtime? I dont need to put the exe in the GAC too do I? I think I am not referencing the dll in the GAC. I guess I am not convinced that the CLR is finding my dll to which the GAC points to.
|
|
|
|
|
Are the assemby versions the same between the one in the GAC and the one not in the GAC?
When you strongly-name an assembly the loading semantics change from just matching the assembly name to including public key token, version, and culture (for resource-only assemblys).
If you are constantly updating the assembly you are trying to load, ensure that the AssemblyVersionAttribute doesn't use * as part of the version number, otherwise the number will change every time you do a build which will require you to recompile your exe and/or provide a publisher policy (see MSDN for more info) so that it loads the correct version on each build.
James
"I despise the city and much prefer being where a traffic jam means a line-up at McDonald's"
Me when telling a friend why I wouldn't want to live with him
|
|
|
|
|
You are correct. The versions do not match. I will try deleting the one in the GAC and reapply gacutil and see how it goes. I have one little concern though. If I am using a using statement such as
# using <reformaterclasslibrary.dll> // in the GAC
do I need to specify version numbers and keys in the using statement. If I have to specify version numbers, or more information (recall that I am doing this on Win XP). How or where do I indicate this?
Thanks for all of your help.
|
|
|
|
|
Well James I am happy to report that we did it and I could not have done it with out your help. There was a slight difference in the minor version number of the shared assembly in the GAC and the one that the GAC pointed to. I am not completely sure how I let that happen, but I did. Perhaps I did a rebuild that I forgot about. I don't know. Also, I put a copy of the same version of that assembly in the debug folder of the client application so I could compile with the same version as was pointed to by the GAC.
The steps I followed...
1) To compile, I put a copy of my shared assembly in the same folder as my project. In the debug folder where my exe goes.
2) I removed the faulty version of the reference in the GAC
3) I readded my shared assembly to the GAC with the gacutil.exe and made absolute certain that the version numbers were exactly the same in the GAC, as assembly that the GAC pointed to and that this was the exact same version number that the client application was compiled with.
I really appreciate your help.
|
|
|
|
|
I havent tried this myself , but I'll have a look in the morning.
<a TITLE="See my user info" href=http:
|
|
|
|
|
Would this be the correct syntax to set the size of a control:
this->Size = System::Drawing::Size (500, 25); If I try using new I get the following two errors: error C2716: 'operator new' allocates value types on the C++ heap; use '__nogc new System::Drawing::Size' and error C2664: 'System::Windows::Forms::Control::set_Size' : cannot convert parameter 1 from 'System::Drawing::Size *' to 'System::Drawing::Size'
adding __nogc fixes the first error but the second still exists.
Thanks
- monrobot13
|
|
|
|
|
If Size is a property, you should use get_Size()
|
|
|
|
|
I don't want to get the size though, I'm trying to set the size of the control. using set_Size and simply Size and the same thing
- monrobot13
|
|
|
|
|
Did this syntax not work? I just tried it in VS.NET 2003 on a button control and it works. I haven't attempted it on VS.NET 2002.
Here is the code that worked for me. All I did was make a new windows forms application and added a button.
<br />
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)<br />
{<br />
Button* btn = __try_cast<Button*>(sender);<br />
<br />
<br />
btn->Size = System::Drawing::Size(100,100);<br />
<br />
}<br />
Later,
Nathan
---------------------------
Hmmm... what's a signature?
|
|
|
|
|
It did work for me as well. I just wasn't sure because I hadn't actually tried running the program before I posted. It did complie though.
- monrobot13
|
|
|
|