|
I've been using a number of third party COM components with VC6 and now that I am migrating to C# I beginning to dive into Interop. The manufacturer of these components won't support .Net and have no intention of migrating in the near future so I am creating wrappers for the components in question. The tlbimp utility fails with a number of errors when converting the type libraries so I am creating the wrappers by hand. So far so good - sort of. I've gotten a number of the functions in a number of the components to be accessible, my problem is finding the right data type to marshal the data as. For instance:
typedef StructList __RPC_FAR *RCStructList;
typedef struct tagSTRUCT1
{
long nVal1;
long nVal2;
double dVal1;
} Struct1;
typedef struct tagSTRUCT2
{
Struct1 S1;
Struct1 S2;
} Struct2;
struct StructNode{
Struct2 __RPC_FAR *pNext;
StructNode node;
};
struct StructList
{
StructNode __RPC_FAR *pFrst;
};
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE
GetList(
/* [in] */ RCStructList rslRequested,
/* [in] */ DWORD dwMin,
/* [in] */ DWORD dwMax,
/* [retval][out] */ StructList rslFetched
) = 0;
OK, so, I converted the first two structures like this:
public struct Struct1
{
public Int32 nVal1;
public Int32 nVal2;
public double dVal1;
}
public struct Struct2
{
Struct1 S1;
Struct1 S2;
}
It seems to work alright. So what do I do about the other two and the function call? And what happens when one of the parameters is a BSTR pointer? I've tried the UnmanagedType.BSTR to no avail, it just keeps throwing a null reference exception. On another note, I've been able to wrap the function calls alright except when the return [retval] is an interface. I use
[return: MarshalAs(UnmanagedType.Interface)] Object func_call();
But it throws an exception saying there's no such interface.
Thank you in advance for any assistance you may provide.
|
|
|
|
|
IntPtr works for all pointer types.
I think you can convert this one
struct StructNode{
Struct2 __RPC_FAR *pNext;
StructNode node;
};
like that
public struct StructNode{
IntPtr next;
IntPtr node
}
You can convert structures with Marshal.StructureToPtr() and re-convert them with Marshal.PtrToStructure().
|
|
|
|
|
I have heard that the ability exists to write Windows application in .NET that will self upgrade (do a version check on startup and silently pull down updates from a server). I suppose that ability exists in any environment if you put enough effort into it, but I was hoping there were some built-in API calls that could be made and a standard mechanism to do this. Has anyone done anything along these lines and can point me to a document or code example. Thank you.
Ron Ward
|
|
|
|
|
Have a look at the App Updater Application Block from MS here[^].
I haven't used it, but HTH.
Cheers,
Simon
sig :: "Don't try to be like Jackie. There is only one Jackie.... Study computers instead.", Jackie Chan on career choices.
article :: animation mechanics in SVG picture :: my first abstract photo
|
|
|
|
|
Thanks Simon. That was the exact article I was looking for.
|
|
|
|
|
Hi,
Can any 1 tell me how I can access COM ports in C#
I'm making a semester project that checks if my Mouse/KBoard etc are plugged in or any Errorz etc occur.
Plz Help
Raheela
|
|
|
|
|
Is there any equivilent in C# of the following C++ construct:
struct Data
{
int val;
char* pStr;
};
Data data[] =
{
{ 0, "Zero" },
{ 1, "One" },
{ -1, NULL }
};
I tried the following, and a few variations, but they didn't work:
public struct Data
{
public int val;
public string str;
};
static public Data data[] =
{
{ 0, "Zero" },
{ 1, "One" },
{ -1, NULL }
};
The following works, but it really bugs me:
public struct Data
{
public int val;
public string str;
public Data(int v, string s) { val = v; str = s; }
};
static public Data data[] =
{
new Data(0, "Zero"),
new Data(1, "One" ),
new Data(-1, NULL )
};
Am I missing something?
Joe Woodbury
When all else fails, there's always delusion.
- Conan O'Brien
|
|
|
|
|
|
jparsons wrote:
What bothers you about this?
For years I programmed in assembly. Ever since part of my brain is always thinking about what is really happening "underneath." I'm not well versed with how ILASM and how .NET actually does certain things. The construct I used looks inefficient, even though it very well may be.
Joe Woodbury
When all else fails, there's always delusion.
- Conan O'Brien
|
|
|
|
|
Well...
<br />
static public Data data[] = {<br />
new Data(0, "Zero"),<br />
new Data(1, "One" ),<br />
new Data(-1, NULL )};<br />
In a sense, it's the only logical thing to do (and allow)..
After all, in C# arrays are actually a type of their own
(unlike the older C style case where an array is just a
pointer).
So, while the first line begins the instanciation of a new
Array of Data, you still have to instanciate and initialize
each data (hence the other lines look like they do).
The longer version of the same code is (forgetting about static and public):
<br />
Data[] data = new Data[3];<br />
data[0] = new Data(0, "Zero");<br />
data[1] = new Data(1, "One");<br />
data[2] = new Data(-1, NULL);<br />
Until the second line, data[0] has not been instanciated to be
a Data object (yet, data[] has been instanciated to be an array of
Data objects that can accomodate 3 Data instances).
Might seem inefficient, but, thinking of the Data instances as objects
of their own right, it makes sense (sort-of)...
..sure, in your case they are structs, but I think that at this point they
just figured it was better to avoid a different syntax for structs vs classes...
I saw this situation in Java the first time,
and it took a bit to get used to it (yeah, I kept on thinking that
after Data[] data = new Data[3] all three data objects where instanciated,
pointing to NULL... again, they are not pointers!).
F.O.R.
|
|
|
|
|
I'm actually not sure what happens in this case. Your data type is a struct so it's a value type. Typically value types are allocated on the stack instead of the heap. However, you're array is most likely (please correct me if I'm wrong here) is a reference type and will be allocated on the heap. So I'm not sure exactly where the value types memory will be allocated.
Jared
jparsons@jparsons.org
www.prism.gatech.edu/~gte477n
|
|
|
|
|
Arrays are reference types, therefore they're always allocated on the heap.
An array of structs is no different -- it'll be on the heap -- however, in this case the memory block on the heap will be a contiguous series of Data structs, one after the other. All that the "new Data()" calls are doing is initializing the various elements of the array.
Cheers, Julian
Program Manager, C#
This posting is provided "AS IS" with no warranties, and confers no rights.
|
|
|
|
|
That's music to my ears.
Joe Woodbury
When all else fails, there's always delusion.
- Conan O'Brien
|
|
|
|
|
I'm putting together initial specs on a new version of a business application.
One of the items on the potential features list is to give the end user the ability to modify one of the main forms in the program. It's database driven and the idea is that they can move around fields (combo boxes, text input boxes etc) to their liking, removing some if not required etc until they have it the way they like it, then save it as a template for others to use.
One wrinkle in this is that we will also have an asp.net presentation layer into the same database that will replicate as closely as possible the winforms appearance. In an ideal world they templates would work with both asp.net and windows forms.
Anyone ever tried this with .net and c# or have any words of inspiration?
Strangers passing in the street
By chance two separate glances meet
And I am you and what I see is me...
|
|
|
|
|
|
Thank you, there is some useful info there and I had not seen that before.
Cheers!
Everybody knows that the bird is the word.
|
|
|
|
|
i have the following problem with a remoting application.
when a client try to register for events of the remote object, the host for these remote objects throws a file not found exception
saying that it can't find client aplication excecutable file in directory where the excecutable for the host application is located.
when i copy the client excecutable file to that derectory it works fine.
i dont know why it needs the client excecutable for that, if object address and method address are contained with the event delegate.
please help me.
|
|
|
|
|
i have dll written in VB 6.0 and it contains some controls.Let's call it MyControls.dll. I imported this dll to my C# project and put controls from it on toolbox.Visual studio created for me AxInterop.Mycontrols.dll,named AxMyControls in solution explorer.So,when i drop a control from toolbox to the form it is AxMyControls.OneControl,not a MyControls.OneControl.
So,when i call function which need a MyControl.OneControl as a parameter,
i have an error passing AxMyControls.OneControl into it.
What should i do? I was trying to create GUI by hand but
MyControls.OneControl ControlObject=new MyControls.OneControl();
does not work cause of
C:\WORK\Karn\ExcellentConverter0.01\ExcellentConverter0.01\FrmImport.cs(59): 'Mycontrols.OneControl.OneControl()' is inaccessible due to its protection level
can i change protection level (private/public) in dll and recompile it?
what is a constructor in VB 6?
thanks for answers
sorri for my english
|
|
|
|
|
Hello,
here is my problem; using the GDI+ i draw a string using DrawString() and i draw a rectangle around this string.
But when i scale the view (to simulate a zoom in or zoom out) the string can becomes larger than the rectangle !
It seems that the true type fonts are not truly scalable.
However i read that the GDI+ subtly manipulates the character and word spacing...
Can you help me ?
Thanks a lot.
|
|
|
|
|
I guess MeasureString() is what you need.
Mazy
No sig. available now.
|
|
|
|
|
Sorry but in my case the rectangle is drawn by the user near the text...
|
|
|
|
|
OlivierMDVY wrote:
It seems that the true type fonts are not truly scalable.
Yes, I've faced this problem as well before.
first of all, how do you perform the zoom in out effect?
if you are usign Graphics scalling technique, you can define the Font size to the point scale,
eg.
Font f = new Font("Courior", 25.4f*50.0f/72f, GraphicsUnit.World);
// the 50f is the default size I used.
then draw it by DrawString(), you can see the scale changed if graphics scale change.
Hope this help~~
|
|
|
|
|
I want to be downloading 5 files simultaneously. I have an array of threads created, each downloading a file. These files though, are actually pages of a book. So I want the thread to download a page only once (of course!). What I wanted to do was to maintain a shared global page number in the main thread, so that when each of the worker thread finishes it's current page, it reads this number, decrements it, and downloads it. Only, two things:
1- I want this number to somehow be stored on disk, so that if a power cut happens, or windows restarts or any of these issues, I'd be able to resume.
2- Of course, I don't want the threads to access the global number at the same time, so that they wouldn't corrupt it. How can I enable this lock?
Thank you very much.
Sammy
"A good friend, is like a good book: the inside is better than the cover..."
|
|
|
|
|
Don't use an array of threads. Use async IO or ThreadPool.QueueUserWorkItem() instead.
Use the C# lock statement or possibly Interlocked.Decrement() to protect your shared state.
Think about the fact that what your just described will not correction resume because you describe decrementing a counter when the download is started. You need to maintain state about which ones are started and which ones are completed. You can't rely on them completing in the order the downloads were started.
Why do you think you need to download five pages simultaneously anyway? That sounds suspect to start with.
--
-Blake (com/bcdev/blake)
|
|
|
|
|
Blake Coverett wrote:
You can't rely on them completing in the order the downloads were started.
Actually, what I was planning to do is, if I detected that the download was interrupted, I would increment this counter by 5, and re-start. This way, all pages that were downloading at that time, will be resumed.
Blake Coverett wrote:
Why do you think you need to download five pages simultaneously anyway? That sounds suspect to start with.
I'm writing a program for someone to parse his daily online reports. It's much faster if I download the html pages simultaneously than to get them one by one. Also, I can parse one page while the other is downloading.
Sammy
"A good friend, is like a good book: the inside is better than the cover..."
|
|
|
|
|