|
Hi guys,
I have the following code in my C# application calling a C++ dll. Please advice if this is a correct way to use a struct.
public struct pTest
{
public StringBuilder Raw;
public StringBuilder trn;
public StringBuilder ece;
public StringBuilder Ct;
public StringBuilder At;
}
[DllImport("c:\\Parser.dll")]
public static extern int Parse(string tst);
[DllImport("c:\\Parser.dll")]
public static extern pTest GetParseData();
#endregion
In my code when I call the functions, as follows
res=POSShare.UtilObj.Parse(stn);
POSShare.UtilObj.GetParseData();
I get the pinvoke error when I call the function. Please help?
sasa
|
|
|
|
|
You should be more specific. What error are you getting? Which function is generating error: is it Parse() or GetParseData()? How does your unmanaged struct look like?
|
|
|
|
|
Thank you Giorgi, Here is C++ dll code that I am trying to call.
typedef struct {
LPTSTR lpsRaw;
LPTSTR lpsTransit;
LPTSTR lpsAccount;
LPTSTR lpsCSN;
LPTSTR lpsAmount;
} LPMICR;
LPMICR (CALLBACK* GetParseData) ();
int (CALLBACK* ParseMICR) (LPTSTR lpStr);
Here is my C# code:
public struct pMICR
{
public StringBuilder Raw;
public StringBuilder Transit;
public StringBuilder Account;
public StringBuilder CSN;
public StringBuilder Amount;
}
[DllImport("c:\\Parser.dll")]
public static extern int ParseMICR(string Micr);
[DllImport("c:\\Parser.dll")]
public static extern pMICR GetParseData();
I am getting the following error: Method's type signature is not pinvoke compatible. This happens when I call getparse data function. Parsemicr function completes just fine.
Please advice.
sasa
|
|
|
|
|
Hi,
if the API is fixed, you will need more C# code to get the marshaling right.
I try to keep P/Invoke stuff as simple as possible, so...
if you can choose the API, I would simplify as much as possible; I suggest you
pass the StringBuilders one by one as parameters to the GetParseData function,
and have it return just some result code (int or bool).
Good practice is to pass the capacity of each of the StringBuilders too.
So it could look like:
[DllImport("c:\\Parser.dll")]
public static extern int GetParseData(StringBuilder Raw, int RawLen, StringBuilder Transit,
int TransitLen, ...);
The native code can accept the data as pointers and lengths, and is allowed to write
to the dereferenced pointer (within the limits of the StringBuilder's capacity, you
really must create them with a sufficient "initial" capacity, they won't be grown by
the native code!)
And if you feel the need to keep the results in a single struct, you could
create one (with strings) and load it from the StringBuilders once GetParseData() returns.
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Hi Luc,
I believe this is the second or third time you have come to my rescue, thank you for that.
yia I agree with you, unfortunately this dll is written by an outside source so I can't modify it. I have requested them to modify it. Hopefully they will do so. Either way you say that I would require more marshalling, what do you mean by that? how would I do it?
Please advice.
sasa
|
|
|
|
|
Hi,
assuming the native code is allocating the strings and just passing pointers to them through
the struct, then you should declare the struct as containing IntPtr, then use one of
the Marshal methods, such as Marshal.PtrToStringAnsi().
BTW some one should sone how free the native strings. What does the API say about that?
Luc Pattyn [Forum Guidelines] [My Articles]
this weeks tips:
- make Visual display line numbers: Tools/Options/TextEditor/...
- show exceptions with ToString() to see all information
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Have you tried decorating the struct with the StructLayoutKind attribute.
[StructLayoutKind.Sequential]
public struct pTest
{
public StringBuilder Raw;
public StringBuilder trn;
public StringBuilder ece;
public StringBuilder Ct;
public StringBuilder At;
}
I always knew that some day I would wake up in the morning and decide to live forever, or die in the attempt.
|
|
|
|
|
yes I have that already and it is still giving me the error. Thank you for your response either way.
sasa
|
|
|
|
|
I want to display a syncfusion menubar alongwith a logo on its side on the top of a Windows Form.How do i go about this?
Keshav Kamat
India
|
|
|
|
|
What's a syncfusion menubar?
3d party control?
If so - does it come with documentation?
-Larantz-
|
|
|
|
|
I'm trying to include a c++ dll in my C# project. Im having some problems. I need to check and see if the problem lies in my C# code, or the C++ DLL code. Can someone link me to a C++ DLL that they know works when called correctly from C#? Something simple that I can test my syntax with. Thanks.
|
|
|
|
|
To call methods from c++ dll by using P/Invoke. To test your c# syntax just call any winapi function so you won't need any extra dll's. For examples of platform invoke have a look at this website: http://pinvoke.net/
|
|
|
|
|
Thanks Giorgi.
|
|
|
|
|
the use of this class inorder to pass data between forms :Application.OpenForms["OpenFormName"].Controls["ControlName"].Text
But I can't manage to use this myself, how do I use it properly to pass data from a variable in class A to a variable in class B??
|
|
|
|
|
Where did you read it? It will have more information about it. Have a look at this too:
http://www.codeproject.com/dotnet/passingvaluesbetweenforms.asp
|
|
|
|
|
|
I'm currently working on a small DLL that enables you to change control names on the fly (e.g. used for swapping languages).
Works fine so far, however I have a problem with the MenuItems.
The names are stored in a text file like this:
FormName.ControlName;english name;german name;french name
However the MenuItems names cant be retrieved at runtime? There is no .Name property for the MenuItems.
Any ideas?
|
|
|
|
|
c0rvus wrote: There is no .Name property for the MenuItems.
There is name property for the menuitem but it is the name of the menu. If you can retrieve the menu object then you can access its items through the MenuItems property
|
|
|
|
|
Hm,.. I know how to retrieve all the MenuItems from the Menu itself but I dont know how to retrieve the name of a MenuItem which is extremly important to me as I need it to create a unique identification for each control.
for instance:
ContextMenu
->mnuItem1
->mnuItem2
->mnuItem3
->mnuSubItem1
->mnuSubItem2
is my menu.
That would mean i had the following entries in my textfile:
Form1.mnuItem1;....;....
Form1.mnuItem2;....;....
so i would try something like this:
private void RenameMenuItem(MenuItem item, string formName)
{
GetName(formName + "." + item.Name) <--- that would be what i'd like it to be
foreach(MenuItem menuItem in item.MenuItems)
{
RenameMenuItems(menuItem);
}
}
You see, I really need the item's name to read the according new name from the text file.
|
|
|
|
|
You might want to be careful changing the Name property of the controls (even MenuItems) at runtime. This property is what the runtime uses to identify each control, not what is displayed on screen. For that, you generally need to change the Text property.
There is a Name property for all UI controls, you may need to cast the object back to a MenuItem in order to access it.
|
|
|
|
|
Thanks. I know that I shouldnt change the Name property (if I remember correctly thats not possible). I do only need it to create a unique identification string to search that in my text files.
I've tried casting MenuItem back into Control but that gives me a compiler error :/
|
|
|
|
|
You shouldn't be casting MenuItem to Control , it should probably be the other direction. The Name property should always be unique (and if you're using the Forms designer it will guarantee that it is) so that should be your key into the text file.
Since you are trying to do localization, is there a reason you aren't using the built-in localization that Windows Forms and .NET provides?
|
|
|
|
|
I'm doing the localization just for educational purposes (or whatever you call that )
Just to know if I can do it.
I think the casting wont work since MenuItem is not derived from the Class (They are both derived from the Form Class if i remember correctly).
After trying for some time now I might stick with the solution to simply get the names of the menu itself and name the MenuItems Form1.mainMenu.Item1 to ...ItemXX. Cant get anything else to work :/
|
|
|
|
|
Hy
I have a RichTextBox.
When I press any alphabetic key on RichTextBox_KeyDown the e.KeyValue have the ascci code for the bigger letter. I press "q" and the e.KeyValue have the ascci code for "Q". How can I detect what key I pressed?
thanks
|
|
|
|
|
You've already identified what key you've pressed. Do you mean how do you work out what character it was? If so, just cast it to a string.
Deja View - the feeling that you've seen this post before.
|
|
|
|