|
We are using an exchange server. Do not know if it supports STMP but without supplying a server it throw an exception Will see what I can find out
|
|
|
|
|
Hello!
I'm starting to use C#, and I feel lost right now.
I've got a "somestruct.h" file with a C++ struct:
struct SOMESTRUCT
{
TCHAR Field1[100];
int Field2;
double Field3;
};
And, in a C++ class, I have a function that returns a SOMESTRUCT:
SOMESTRUCT someFunction();
Now I have a C# app which will call the C++ function. I have the C++ code in a DLL and I try to import the DLL so I can call that function:
[DllImport("myDLL.dll", CharSet = CharSet.Auto)]
static extern SOMESTRUCT someFunction();
Problem is: my C# app doesn't know the SOMESTRUCT struct. I can't import "somestruct.h" in C# and I really don't know how could I use that function.
I think maybe I could make a managed version of the struct SOMESTRUCT, but I don't know how to transform a fixed-size char array (Field1). If I transform it to a String it doesn't work properly.
I have also read that I could make a wrapper of the struct to get it work from C#, but I just cannot find an easy-to-understand, newbie-suitable, complete example of how to do it.
Please, could somebody help me?
|
|
|
|
|
verence333 wrote: Please, could somebody help me?
Learn C# first, then move onto more advanced topics like platform invoke (calling a native dll).
|
|
|
|
|
Hi, leppie.
Well, I'm trying to learn C# already. But I'm not learning it because I want, but because I'm required to get an application working. That application uses some C++ DLL's, and I *must* use them. Also, I don't have all the time in the world to learn how to do it, it should be done in a limited time, so I must learn advanced topics already.
I think I have no problem with C# language, it's very easy to understand and use, and the only things that trouble me are those advanced topics. I already know how to invoke functions from native DLL's, but only functions that return a standard type (int, long, etc.), and I can't find info about how to invoke functions that return a struct.
Thanks.
|
|
|
|
|
I suggest you lookup on Marshalling structures, that should give you the answer you are looking for, whether it will be understood is another story.
Good luck
|
|
|
|
|
OK, thank you. I'll try to find that. I've already learnt something about marshalling, like for example:
(SOMESTRUCT) aaa = (SOMESTRUCT)Marshal.PtrToStructure(param, typeof(SOMESTRUCT));
And it works if SOMESTRUCT is defined in the C# app. But, what if it isn't, and is a struct that is in a C++ DLL? I just can't cast to a SOMESTRUCT.
I hope I can find that info searching for what you suggest. Anyway, if somebody has more suggestions, I will be glad to read them.
Thank you!
|
|
|
|
|
verence333 wrote: And it works if SOMESTRUCT is defined in the C# app. But, what if it isn't, and is a struct that is in a C++ DLL? I just can't cast to a SOMESTRUCT.
No you cant. You have to define it in C# somewhere so the magic can work
verence333 wrote: (SOMESTRUCT) aaa = (SOMESTRUCT)Marshal.PtrToStructure(param, typeof(SOMESTRUCT));
You do not need it that explicity most of the time. Eg
extern static void Foo(ref SOMESTRUCT s);
See! All magic
|
|
|
|
|
Interesting, thanks again.
I've come up to this url:
http://msdn.microsoft.com/en-us/library/ms384329(VS.71).aspx[^]
There, they explain how to make it, but the examples don't work. For example, the following line:
MCITY(String* name,int x,int y)
and this other:
String* name;
Throw an error: "Cannot take the address of, get the size of, or declare a pointer to a managed type ('string')". So I still don't know how to marshall a char pointer or char array. :-/
Anyway, it's a start.
|
|
|
|
|
There are several attributes in the System.Runtime.InteropServices namespace that will be useful here. You could try something like this:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct SOMESTRUCT
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst:=100)]
string Field1;
int Field2;
double Field3;
}
I don't know if that should be SizeConst:=100 or just SizeConst=100; I just copied it from the VB editor. At the very least, that should point you in the right direction.
|
|
|
|
|
Wow! Thank you so much, Gideon! Yes, it really helped a lot! (BTW, it's just SizeConst=100)
I could never think that finding this answer was so difficult. I've been searching and asking for several days with no results until now.
|
|
|
|
|
Hi!
Gideon, yesterday I used your code to solve the problem, but I needed to add just a little thing (the charset in the StructLayout should be equivalent to the one used in the C++ struct; I just used "Auto" and it works). Just in case somebody has the same question, I'll write it here:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct SOMESTRUCT
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=100)]
string Field1;
int Field2;
double Field3;
}
Thank you very much.
|
|
|
|
|
I had a similar problem, and I was able to avoid the complexities of marshalling by defining the same structure in both C# and C++.
A "char" is C# is NOT the same as a "char" in C++. C# uses unicode chars, which are usually longer than one byte. But a C# "byte" IS the same as a "char" in C++.
After you have what appear to be equivalent structures in both languages, write a test program that sets values in one, and see if you can pass it to the other unchanged. You can also use the sizeof () operator to see if the structure is the same size in both languages. (C# allows sizeof () to be used in unsafe mode.)
Ints and doubles are the same in both languages.
|
|
|
|
|
Thank you, Alan. I tried to write the equivalent struct, but my problem was when translating a char[100]. C# does not allow me to make structures with fields that have been initialized to a size. So, if I write this inside a struct in C#:
public byte[] bytes = new byte[100];
I have the following error: "cannot have instance field initializers in structs".
Thanks for the rest of your message, I'll test my program as you suggest. In fact, I tried to do this before, but I couldn't use sizeof() and forgot it; didn't knew I could use it in unsafe mode.
|
|
|
|
|
|
Awesome! Thank you very much, Alan! This makes my job MUCH easier.
|
|
|
|
|
Hi.
Can anyone describe that clearly ?
Thank you.
|
|
|
|
|
An assembly is either an EXE or a DLL.
|
|
|
|
|
blackjack2150 wrote: An assembly is either an EXE or a DLL.
Means for example MyApplication.exe is an assembly file ?
|
|
|
|
|
IF it is written in a .NET language, yes, it is an assembly.
|
|
|
|
|
Thank you leppie .
Then What's difference between them (DLL files & assembly files)
|
|
|
|
|
A dll can be either a native dll or a .NET assembly. The subject is very broad and I suggest you read up in MSDN on how the CLR works.
|
|
|
|
|
|
|
Glad to help you
Giorgi Dalakishvili
#region signature
my articles
#endregion
|
|
|
|
|
Lol, I think we should just point everyone to Wikipedia
|
|
|
|