Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / May 2008

Tip: Looking for answers? Try searching our database.

Get C# reference to an object from a void C++ method

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Joachim Van den Bogaert - 09 May 2008 12:56 GMT
Hi,

I have a method in C++:

DLLEXPORT void * hunspell_initialize(char *aff_file, char *dict_file)
{
   Hunspell * pMS = new Hunspell(aff_file, dict_file);
   return pMS;
}

1. Can anyone explain how this void method can return a new Hunspell
object?

I'm new to C++. I suppose it has something to do with pointers (is it
correct to say that the void method is a pointer to the address where
the Hunspell object is located in memory?).

2. Can anyone tell me how I get a reference to the Hunspell object in
C#?

Currently I have this code:

[DllImport("libhunspell.dll", EntryPoint="hunspell_initialize")]
public static extern void hunspell_initialize(ref string affixPath,
ref string dictionaryPath);

but as you can see, I do not have any reference to the Hunspell
object,

Thanks,
Joachim
Giovanni Dicanio - 11 May 2008 09:55 GMT
> I have a method in C++:
>
[quoted text clipped - 6 lines]
> 1. Can anyone explain how this void method can return a new Hunspell
> object?

This method returns a 'void *'.
'void *' in C/C++ means "a pointer to something...", but what the
"something" actually is, is not specified.

I believe that the purpose of that code is to make Hunspell instances
"opaque".
Each Hunspell instance (created in the function body, using C++ operator
'new'), is "masked" using a 'void*', a void pointer, a "pointer to
something".
In 32 bits platforms, a void* is a 4-bytes (32-bits) data, which stores an
address which points to something.

I think that your library uses 'void *' (4 bytes data) to uniquelly identify
Hunspell instances. The fact that void* points to an Hunspell instance is an
implementation detail, it is hidden behind a black-box. What is seen at the
public interface is just a void*, a pointer to something.

So, I think that you will also have some functions like
hunspell_uninitialize, that may work like this:

void hunspell_uninitialize( void * x )
{
    // The 'void *' is a pointer to Hunspell instance
    Hunspell * hunspell = (Hunspell *)x;
    delete hunspell;
}

and if Hunspell class has a method like do_something, I believe that you
will have a function like this:

void hunspell_do_something( void * x )
{
   Hunspell * hunspell = (Hunspell *)x;
   x->do_something();
}

i.e. you are using a code that is wrapping a C++ class (Hunspell) using a
C-like function-based interface (and the class instance is identified by
"opaque" 'void *').

> 2. Can anyone tell me how I get a reference to the Hunspell object in
> C#?
[quoted text clipped - 7 lines]
> but as you can see, I do not have any reference to the Hunspell
> object,

I think that the above C# code does not correctly map the aforementioned C++
hunspell_initialize function.
In fact the hunspell_initialize function returns 'void *', but your C# code
specifies that the return value is 'void'.

'void *' and 'void' are completely different things: 'void *' is a generic
pointer to something, instead 'void' means "nothing", "no return value".
I think that the correct mapping from C++ 'void *' in C# is 'IntPtr'.
So in your C# code you should specify that hunspell_initialze returns an
'IntPtr'.

Note that I think that you will not see any explicit reference to 'Hunspell'
class, you will just identify instances of 'Hunspell' class using 'IntPtr's.

(Of course, you may build a C# object-oriented wrapper to the C-like
function-based interface).

class Hunspell
{
  // Identify current Hunspell instance
  private IntPtr id_;

  // Constructor - initializes Hunspell
  public Hunspell( ...initialization parameters )
  {
       id_ = hunspell_initialize( ...init parameters ... );
  }

  public void DoSomething()
  {
      // Call C-like do_something function
      hunspell_do_something( id_ );
  }

  ...

}

HTH,
Giovanni
Joachim Van den Bogaert - 13 May 2008 08:53 GMT
Hi Giovanni,

Thanks for the explanation. This was really helpful.
If I understand correctly, I return an IntPtr whenever C++ returns
void *.
As for the rest of my code I will have to define some structs that map
the classes that are being used in the C++ code.
I found most what I need here:

http://msdn.microsoft.com/en-us/library/eshywdt7(printer).aspx

Regards,
Joachim
Giovanni Dicanio - 13 May 2008 09:28 GMT
> Thanks for the explanation.

You're welcome.

> If I understand correctly, I return an IntPtr whenever C++ returns
> void *.

Yes, I think that in your sample code you should "map" C++ 'void *' with
IntPtr in C#.

Giovanni

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.