473,503 Members | 1,804 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C# program calling a C++ DLL

Hello,
I received a C++ DLL and I must include it in my C# programm. The
problem is that I don't know how to convert the parameters from C++ to C#,
specialy when there are pointers in it. There are 2 fonctions I would like
to convert.

The first one has only one parameter, but I don't know how to deal with
the void type.

[C++]
long myFunction1(void ** parameter);

I tried this, but it does not work:

[C#]
[DllImport("MyDLL.dll")]
public static extern long myFunction1(ref IntPtr parameter);


The second one has a double pointer to a structure. I think I dealed
with the structure, but what about the double pointer ?

[C++]
long myFunction2(myStruct** parameter);

with myStruct defined as:

struct FF_AO_ImageList
{
char structParameter1[30];
long structParameter2;
}

[C#]
[DllImport("MyDLL.dll")]
public static extern long myFunction2(??????);

with myStruct defined as:

public struct FF_AO_ImageList
{
[MarshalAs(UnmanagedType.ByValTStr), SizeConst = 30]
public string structParameter1;
public long structParameter2;
}
I hope it's not too difficult to understand, however I'll explain again.
I hope someone can help me ! Thanks...
Laurent
Nov 24 '05 #1
9 9216
Laurent, your code example for the void pointer looks okay. The thing
with P/Invoke is you need to have a bit more understanding of the
unmanaged types and you seem to have got it with the first function.

void** is roughly equivalent to passing your IntPtr by ref - but then
again does the DLL expect the pointer to be pointing to some valid
data? In which case you will need to use the Marshal COMInterop class
to do some tweaky Writes directly to unmanaged memory.

The second function is a little more tricky. It expects a pointer to a
pointer to a value type (struct). Now as long as the structure layout
is as expected by the DLL, you should actually create a *class* (which
is implicitly passed by reference always) and pass your class i.e. the
FF_AO_ImageList (declare as class, not "struct"), by ref.

Two other things I noticed - ensure you explicitly set the
CallingConvention attribute (CDecl? StdCall?); Also decorate your
class with the StructLayoutAttribute (most likely layout type is
"Sequential"). See Adam Nathan's www.PInvoke.net as well for plenty of
examples.

Nov 24 '05 #2
Hi Kofi,
Thanks for your answer. I'm trying to use only the first function with
the void** parameter. I think the DLL will allocate the memory so I don't
have to do it by myself. Anyway, the code always throws a
System.EntryPointNotFoundException with the following message: "Unable to
find the Entry Point "xxxx" in the DLL "xxxx.dll".

I opened a DLL using "DLL Depends 2.1"... The tool shows me the function
I would like to call with an entry point adress. Prehaps the DLL has not
been well compiled ?

I don't know what I did wrong. I tried to use an unsafe code and a
void** parameter, but the same error occured. I'll try using a C++ code to
call my DLL, just to see if I can access the function...
If anyone has an idea...

"Kofi" <ko**@nimoh.com> a écrit dans le message de news:
11**********************@f14g2000cwb.googlegroups. com...
Laurent, your code example for the void pointer looks okay. The thing
with P/Invoke is you need to have a bit more understanding of the
unmanaged types and you seem to have got it with the first function.

void** is roughly equivalent to passing your IntPtr by ref - but then
again does the DLL expect the pointer to be pointing to some valid
data? In which case you will need to use the Marshal COMInterop class
to do some tweaky Writes directly to unmanaged memory.

The second function is a little more tricky. It expects a pointer to a
pointer to a value type (struct). Now as long as the structure layout
is as expected by the DLL, you should actually create a *class* (which
is implicitly passed by reference always) and pass your class i.e. the
FF_AO_ImageList (declare as class, not "struct"), by ref.

Two other things I noticed - ensure you explicitly set the
CallingConvention attribute (CDecl? StdCall?); Also decorate your
class with the StructLayoutAttribute (most likely layout type is
"Sequential"). See Adam Nathan's www.PInvoke.net as well for plenty of
examples.

Nov 25 '05 #3
Hi Laurent,

If you can see the DLL function with Depends then it is likely you
should be able to call it ok. Doing a quick check calling it from C++
is a good idea - I notice you did not mention whether you used the
CallingConvention attribute in your last post, it might be an idea to
use the ExactSpelling attribute as well. Plus (I'm sorry, dumb
question but you never know), is your DLL in the correct directory?
i.e. the bin/Debug directory most likely, while you're debugging? It
is a few months since I last used P/Invoke but I always found that you
end up frustrated for a few days and then once you get things working
you remember all the gotchas.

On the void** issue, another thing I can suggest is to try using the
OutAttribute on your function prototype instead like so:

[C#]
[DllImport("MyDLL.dll", EntryPoint="myFunction1", ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)] public static extern long
myFunction1([Out] IntPtr parameter);

Note that your calling convention above may not be StdCall...

Hope this helps!

Nov 25 '05 #4
Hi Kofi,

I found a sample code in C++, but to make it work I had to use the .lib
file. It's a long time since I programmed in C++ so I don't remember well
how it works. Anyway I can access the function.

For my C# code, I tried like this:

[DllImport("myLib.dll", EntryPoint="myFunction1", ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern unsafe long myFunction1(void** outInstance);

[DllImport("myLib.dll", EntryPoint="myFunction1", ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern long myFunction1(out IntPtr outInstance);
The error is always the same: Cannot find EntryPoint. I don't know what
to do next. Thanks for your help anyway !


"Kofi" <ko**@nimoh.com> a écrit dans le message de news:
11*********************@g14g2000cwa.googlegroups.c om...
Hi Laurent,

If you can see the DLL function with Depends then it is likely you
should be able to call it ok. Doing a quick check calling it from C++
is a good idea - I notice you did not mention whether you used the
CallingConvention attribute in your last post, it might be an idea to
use the ExactSpelling attribute as well. Plus (I'm sorry, dumb
question but you never know), is your DLL in the correct directory?
i.e. the bin/Debug directory most likely, while you're debugging? It
is a few months since I last used P/Invoke but I always found that you
end up frustrated for a few days and then once you get things working
you remember all the gotchas.

On the void** issue, another thing I can suggest is to try using the
OutAttribute on your function prototype instead like so:

[C#]
[DllImport("MyDLL.dll", EntryPoint="myFunction1", ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)] public static extern long
myFunction1([Out] IntPtr parameter);

Note that your calling convention above may not be StdCall...

Hope this helps!

Nov 25 '05 #5
Quite a while since I did any hardcore C++ too, but looks like what you
have is some name-mangling issues. BTW the function signature I put in
my last post was just an example, and there are other choices of
calling convention to try - I expect that your dll is more likely to be
"CallingConvention.CDecl". Having said that, considering the error you
are getting I don't believe that to be the problem anyway, but bear it
in mind. Try calling the DLL from C# using just the entry point
ordinal only:-

[DllImport("dllname", EntryPoint="#123")]

Where #123 is the ordinal position of the function. (I am not quite
sure how you determine this if you don't have the code yourself.
Depending on how the DLL was constructed, that kind of info normally
goes into a .DEF file - but I am showing my age...)

I'm afraid I have reached a dead end now I think...

Nov 25 '05 #6
Hi Kofi,
Thanks again for your answer and your patience. I think you found a
clue: I can access my function using the ordinal !

I used the commande dumpbin -exports myLib.dll, and I saw that the
functions where given strange names. I think that the guy who compiled the
DLL did not use the extern "C" function to compile his DLL.

You were very helpful, thanks again !


"Kofi" <ko**@nimoh.com> a écrit dans le message de news:
11**********************@g49g2000cwa.googlegroups. com...
Quite a while since I did any hardcore C++ too, but looks like what you
have is some name-mangling issues. BTW the function signature I put in
my last post was just an example, and there are other choices of
calling convention to try - I expect that your dll is more likely to be
"CallingConvention.CDecl". Having said that, considering the error you
are getting I don't believe that to be the problem anyway, but bear it
in mind. Try calling the DLL from C# using just the entry point
ordinal only:-

[DllImport("dllname", EntryPoint="#123")]

Where #123 is the ordinal position of the function. (I am not quite
sure how you determine this if you don't have the code yourself.
Depending on how the DLL was constructed, that kind of info normally
goes into a .DEF file - but I am showing my age...)

I'm afraid I have reached a dead end now I think...

Nov 25 '05 #7
You may find this site usefull

http://www.pinvoke.net/

Nov 25 '05 #8
Laurent.... You can call the function using the mangled name as in:

To call a function using its fully decorated name "?fnWin32Test2@@YAJXZ"
as
"Win32Test2" you can specify the static entry point as
"?fnWin32Test2@@YAJXY":

[DllImport("Win32Test.dll", EntryPoint= "?fnWin32Test2@@YAJXZ")]
public static extern int fnWin32Test2();

And call it as:

System.Console.WriteLine(fnWin32Test2());

To look at the undecorated name use the undname tool as in:
undname ?fnWin32Test@@3HA

This converts the decorated name to "long fnWin32Test".

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 25 '05 #9
This should make it clear:

http://www.codeproject.com/csharp/EssentialPInvoke.asp

----------
Good Luck
Sharon
Nov 27 '05 #10

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

Similar topics

6
5308
by: Eric Entressangle | last post by:
Hi all, is there any trouble setting an C++ static class method as callback function for a C program or library ? Thanks
0
1714
by: szehau | last post by:
Hi all, I have a program written in C with embeded SQL. Following are the configuration: DB2/LINUX 8.1.5 Thread model: posix gcc version 3.2 20020903 (Red Hat Linux 8.0 3.2-7) My problems...
10
1993
by: free2cric | last post by:
Hi, FOllowing is a program which is written by someone else. Its output is a wonderful poem. I dont understand how it works really. can anyone tell. thanks cric #include <stdio.h> main(int...
6
1285
by: James | last post by:
hello, The program given below is giving segmentation fault. By debugging I inferred that the problem is in the statement t1.f(), but I am not sure that what is the problem. #include <stdio.h>...
8
6423
by: koorb | last post by:
I am starting a program from a module with the Sub main procedure and I want it to display two forms for the program's interface, but when I run the program both forms just open and then program...
18
3105
by: ben.carbery | last post by:
Hi, I have just written a simple program to get me started in C that calculates the number of days since your birthdate. One thing that confuses me about the program (even though it works) is...
24
6547
by: John | last post by:
I know this is a very fundamental question. I am still quite confused if the program call stack stack should always grows upwards from the bottom, or the opposite, or doesn't matter?? That means...
0
7113
by: vve | last post by:
I'm discovering a strange behaviour in an C# project using ZedGraph (https://sourceforge.net/projects/zedgraph/). After adding a signal to it, it seems that the clr goes mad for some reason. I...
38
2626
by: abasili | last post by:
Hi everyone, I'm trying to compile a C++ function and then call it from a C program. Since Google is my friend I've ended up to this link which seems very clear: ...
2
2749
by: John Wright | last post by:
I have a central program I am starting to develop that will track processing deviations. This program is VB 2008 and needs to be called from VB 2005 programs and VB2008 programs (we have some VB 6...
0
7274
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7323
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6984
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7453
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
5005
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4670
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
1507
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
732
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
377
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.