473,225 Members | 1,319 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,225 software developers and data experts.

Calling C++ function from C#

I need to call the below function from a C# application. Having
problems converting it to C#. I think the BOOLs are just integers in
C#. I have tried char[] and string for the PAWDOBJKEY. I always get
"ERROR_BAD_PARAM" for a return value.

SHORT APIENTRY AwdApiInsertItemKey(
HWND hwndContainer,
PAWDOBJKEY pAwdObjParentKey,
PAWDOBJKEY pAwdObjKey,
BOOL fUpdateCount,
BOOL fLockFlag,
PVOID pReserved);

Parameters
hwndContainer: A handle to the container in which you want to
insert an item.
pAwdObjParentKey: A pointer to the key of an existing parent of
the item to be inserted. If NULL, the item is inserted at the root.
pAwdObjKey: A pointer to the key of the item to insert. A view
call is made to get all the needed information to insert the item.
fUpdateCount: This parameter is ignored.
fLockFlag: Specifies whether or not to lock the object on
insertion. True=Lock False=Donít Lock.
pReserved: Reserved for future use; it should be NULL.
=================
AWDOBJKEY
Data that uniquely defines an AWD object. This data
distinguishes the object from other objects of the same type.
Typedef struct awdobjkey
{
CHAR crdattim [26];
CHAR recordcd;
CHAR crnode[2];
} AWDOBJKEY, *PAWDOBJKEY;

==============
Aug 19 '08 #1
4 1743
On Aug 19, 6:10*pm, cozumeldi...@comcast.net wrote:
I need to call the below function from a C# application. Having
problems converting it to C#. I think the BOOLs are just integers in
C#.
It will work, but you can also use "bool" just fine - it maps to 4-
byte WinAPI-style BOOL by default.
I have tried char[] and string for the PAWDOBJKEY. I always get
"ERROR_BAD_PARAM" for a return value.

* * SHORT APIENTRY AwdApiInsertItemKey(
* * * * * * * * * * *HWND hwndContainer,
* * * * * * * * * * *PAWDOBJKEY pAwdObjParentKey,
* * * * * * * * * * *PAWDOBJKEY pAwdObjKey,
* * * * * * * * * * *BOOL fUpdateCount,
* * * * * * * * * * *BOOL fLockFlag,
* * * * * * * * * * *PVOID pReserved);

* * Parameters
* * * hwndContainer: * *A handle to the container in which you want to
insert an item.
* * * pAwdObjParentKey: A pointer to the key of an existing parent of
the item to be inserted. If NULL, the item is inserted at the root.
* * * pAwdObjKey: * * * A pointer to the key of the item to insert. A view
call is made to get all the needed information to insert the item.
* * * fUpdateCount: * * This parameter is ignored.
* * * fLockFlag: * * * * * * * *Specifies whether or not to lock the object on
insertion. True=Lock False=Donít Lock.
* * * pReserved: * * * * * * * *Reserved for futureuse; it should be NULL.
* =================
* * AWDOBJKEY
* * * Data that uniquely defines an AWD object. This data
distinguishes the object from other objects of the same type.
* * * Typedef struct awdobjkey
* * * * * * {
* * * * * * * CHAR crdattim [26];
* * * * * * * CHAR recordcd;
* * * * * * * CHAR crnode[2];
* * * * * * } AWDOBJKEY, *PAWDOBJKEY;
I don't see why you should use char[] or string for AWDOBJKEY, since
it's a struct. So you need to create a corresponding C# struct:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct ADWOBJKEY
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=26)]
string crdattim;

char recordcd;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=2)]
string crnode;
}

And then PAWDOBJKEY is just a pointer, which (if you want to avoid
pointers in C#) translates to a "ref" argument of the method:

short AwdApiInsertItemKey(
* * * * * * * * * * IntPtr hwndContainer,
* * * * * * * * * * *ref AWDOBJKEY pAwdObjParentKey,
* * * * * * * * * * *ref AWDOBJKEY pAwdObjKey,
* * * * * * * * * * *bool fUpdateCount,
* * * * * * * * * * *bool fLockFlag,
* * * * * * * * * * *IntPtr pReserved);

Depending on whether the C++ code also includes some #pragma pack
directives (or is compiled with the corresponding compiler options),
you might also need to set StructLayoutAttribute.Size on the struct
declaration.
Aug 19 '08 #2
Thank you for your reply. Your code almost does the trick. I can do a
trace on the C++ function and it looks to me that when the C++
function get the data it is a little off. I am sending
"2008-06-13-03.54.36.420704" for the crdattim, 'T' for the recordcd
and "01" for the crnode. The first trace below is from another
application that calls this function, the second from my app. Looks
like the last character in the 2 strings is messed up. the last
character of the 1st string is a "0" and the last character of the
second string is a "."

Any ideas?

Good call:
DATA: 56 bytes
56 49 45 57 41 43 42 4C 30 30 31 38 58 58 58 58
<VIEWACBL0018XXXX>
58 58 58 58 30 30 30 30 30 31 4C 32 30 30 38 2D <XXXX000001L2008-
>
30 36 2D 31 33 2D 30 33 2E 35 34 2E 33 36 2E 34 <06-13-03.54.36.4>
32 30 37 30 34 54 30 31
<20704T01 >

Bad call:
DATA: 56 bytes
56 49 45 57 41 43 42 4C 30 30 31 38 58 58 58 58
<VIEWACBL0018XXXX>
58 58 58 58 30 30 30 30 30 31 52 32 30 30 38 2D <XXXX000001R2008-
>
30 36 2D 31 33 2D 30 33 2E 35 34 2E 33 36 2E 34 <06-13-03.54.36.4>
32 30 37 30 30 54 30 00
<20700T0. >
Aug 21 '08 #3
On Aug 22, 12:42*am, cozumeldi...@comcast.net wrote:
Thank you for your reply. Your code almost does the trick. I can do a
trace on the C++ function and it looks to me that when the C++
function get the data it is a little off. I am sending
"2008-06-13-03.54.36.420704" for the crdattim, 'T' for *the recordcd
and "01" for the crnode
Oh, so those strings are fixed length and not null-terminated (since
you are passing 2 chars to a char[2], which leaves no space for a
terminating '\0').

. The first trace below is from another
application that calls this function, the second from my app. Looks
like the last character in the 2 strings is messed up. the last
character of the 1st string is a "0" and the last character of the
second string is a "."
.NET assumed C-style null-terminated strings, and therefore replaced
the last character with '\0' for both strings (a single char was
marshalled fine because it's not a string).
Unfortunately, it means that you cannot use string marshalling (it
always assumes null terminator), and will have to work directly with
byte arrays. So:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct ADWOBJKEY
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=26)]
byte[] crdattim;

char recordcd;

[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
byte[] crnode;
}

To convert .NET strings to byte arrays and back, you use
Encoding.GetBytes() and Encoding.GetString() methods. The default
system encoding is Encoding.Default (it will be the same as using
CharSet.Ansi in earlier declarations).
Aug 22 '08 #4
Thank you very much. It now works. You are a genius.

On Aug 22, 1:23 am, Pavel Minaev <int...@gmail.comwrote:
On Aug 22, 12:42 am, cozumeldi...@comcast.net wrote:
Thank you for your reply. Your code almost does the trick. I can do a
trace on theC++function and it looks to me that when theC++
function get the data it is a little off. I am sending
"2008-06-13-03.54.36.420704" for the crdattim, 'T' for the recordcd
and "01" for the crnode

Oh, so those strings are fixed length and not null-terminated (since
you are passing 2 chars to a char[2], which leaves no space for a
terminating '\0').

. The first trace below is from another
application that calls this function, the second from my app. Looks
like the last character in the 2 strings is messed up. the last
character of the 1st string is a "0" and the last character of the
second string is a "."

.NET assumed C-style null-terminated strings, and therefore replaced
the last character with '\0' for both strings (a single char was
marshalled fine because it's not a string).
Unfortunately, it means that you cannot use string marshalling (it
always assumes null terminator), and will have to work directly with
byte arrays. So:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]structADWOBJKEY
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=26)]
byte[] crdattim;

char recordcd;

[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
byte[] crnode;

}

To convert .NET strings to byte arrays and back, you use
Encoding.GetBytes() and Encoding.GetString() methods. The default
system encoding is Encoding.Default (it will be the same as using
CharSet.Ansi in earlier declarations).
Aug 22 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Muthu | last post by:
I've read calling conventions to be the order(reverse or forward) in which the parameters are being read & understood by compilers. For ex. the following function. int Add(int p1, int p2, int...
6
by: jchao123 | last post by:
Dear All, I have an MDB file (Access 2000/XP) which contains generic routines I use in various apps (eg, API calls, File access classes etc). I have compiled into an MDE file which I reference...
14
by: ericellsworth | last post by:
Hi, I'm trying to use a class to pass variables back and forth from a form opened in dialog mode. I have created a class which invokes a form in its show method, like so: Public Sub Show() '...
1
by: Jesse McGrew | last post by:
Hi all, I'm trying to make a plugin DLL for a third-party application, using VC++ .NET 2003. This DLL acts as a bridge between the C++ plugin API of the application, and my actual plugin code...
5
by: Nick Flandry | last post by:
I'm running into an Invalid Cast Exception on an ASP.NET application that runs fine in my development environment (Win2K server running IIS 5) and a test environment (also Win2K server running IIS...
2
by: Geler | last post by:
A theoretical question: Sorry if its a beginner question. Here is a quote from the MSDN explaning the C/C++ calling convention.. It demonstrates that the calling function is responsible to clean...
18
by: John Friedland | last post by:
My problem: I need to call (from C code) an arbitrary C library function, but I don't know until runtime what the function name is, how many parameters are required, and what the parameters are. I...
15
by: dspfun | last post by:
Hi, Is it possible to print the function name of the calling function? For example, f1() and f2() both calls f3(), in f3() I would like to print the name of the function calling f3() which...
11
by: briankirkpatrick | last post by:
Forgive me if my post seems a little amateurish... I'm requesting assistance from some of you smart folks out there to get the managed calls write that meet the specification in the esa.h for...
16
by: teju | last post by:
hi, i am trying 2 merge 2 projects into one project.One project is using c language and the other one is using c++ code. both are working very fine independently.But now i need to merge both...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: veera ravala | last post by:
ServiceNow is a powerful cloud-based platform that offers a wide range of services to help organizations manage their workflows, operations, and IT services more efficiently. At its core, ServiceNow...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.