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 / Languages / Managed C++ / May 2007

Tip: Looking for answers? Try searching our database.

Pointers btwn C# and C++

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Joachim - 24 May 2007 17:15 GMT
I have a native C++ pointer object which I need to hold in a C# environment,
initialize in the C++ environment and the pass between the C# and C++
environments. Which is the data structure to use? I have tried to use an
IntPtr in C#, send it through C++/CLI as a System::IntPtr and convert it to a
pointer of my class in the end, but that gives compilation errors. What I
guess I need is som C# equivalence to a void* to keep in the C# environment.
But I have no clue how to do it...
Mattias Sjögren - 24 May 2007 17:46 GMT
>I have tried to use an
>IntPtr in C#, send it through C++/CLI as a System::IntPtr and convert it to a
>pointer of my class in the end, but that gives compilation errors.

Can you post the errors and your code? Using IntPtr should work
nicely. You can also use an actual void* in C# if you enable unsafe
code.

Mattias

Signature

Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Joachim - 25 May 2007 08:08 GMT
The C# app:

IntPtr m_DVPSDK_ptr;

       [DllImport(g_wrapper_dll_path)]
       static extern int Initialize(
           out IntPtr class_ptr,
           ref int[] devices_ids,
           Int32 encoder_id);

       [DllImport(g_wrapper_dll_path)]
       static extern string GetLastError(
           IntPtr class_ptr,
           Int32 encoder_id);

       void Initialize()
       {
           int[] l_devs_ids = new int[g_max_devices];
           int l_nr_of_devices = Initialize(
               out m_DVPSDK_ptr,
               ref l_devs_ids,
               m_settings.EncoderId);

           if (l_nr_of_devices == 0)
           {
               //TODO: throw error?
           }
       }

The C++/CLI code:

    extern "C" int Initialize(
        System::IntPtr class_ptr,
        array<int>^ devices_ids,
        int encoder_id)
    {
        return Impl::Initialize(
            (DVP1412DLL*) class_ptr,  //ERROR 2 BELOW
            devices_ids,
            encoder_id);
    }

Error    2    error C2440: 'type cast' : cannot convert from 'System::IntPtr' to
'DVP1412DLL *'

    extern "C" const System::String^ GetLastError(
        System::IntPtr class_ptr,
        int encoder_id)
    {
        return Impl::GetLastError(
            (DVP1412DLL*) class_ptr,  //ERROR 12 BELOW
            encoder_id);
    }

Error    12    error C2440: 'type cast' : cannot convert from 'System::IntPtr' to
'DVP1412DLL *'

> >I have tried to use an
> >IntPtr in C#, send it through C++/CLI as a System::IntPtr and convert it to a
[quoted text clipped - 5 lines]
>
> Mattias
Joachim - 25 May 2007 14:39 GMT
Seemed like it had to do with that I declared the functions as

__declspec(dllexport)

However, even though it compiles, the value of the IntPtr is not changed in
C# even though it is in C++

> The C# app:
>
[quoted text clipped - 62 lines]
> >
> > Mattias
Ben Voigt - 25 May 2007 20:46 GMT
> Seemed like it had to do with that I declared the functions as
>
[quoted text clipped - 3 lines]
> in
> C# even though it is in C++

a C# ref or out parameter must be declared in C++/CLI as a reference
parameter.

>> The C# app:
>>
[quoted text clipped - 5 lines]
>>             ref int[] devices_ids,
>>             Int32 encoder_id);

Don't do this.  To use C++/CLI functions from C#, add a reference to the
generated DLL.

>>         [DllImport(g_wrapper_dll_path)]
>>         static extern string GetLastError(
[quoted text clipped - 24 lines]
>> return Impl::Initialize(
>> (DVP1412DLL*) class_ptr,  //ERROR 2 BELOW

Should be class_ptr->ToPointer(), but see below...

>> devices_ids,
>> encoder_id);
>> }

The compiler shouldn't even allow what you're doing... you have managed
types as parameters, and those are limited to member methods of managed
types.  Create a ref class and make these functions static methods within
that class.  Or, make them instance methods, so you don't have to pass
around class_ptr.

You're also missing a level of indirection all over the place here.  You
want Impl::Initialize to fill in the pointer, right?

Then:

int Initialize( System::IntPtr% class_ptr,  array<int>^ devices_ids, int
encoder_id)
{
   DVP1412DLL objectPointer;
   int retval = Impl::Initialize(&objectPointer, devices_ids, encoder_id);
   class_ptr = gcnew System::IntPtr(objectPointer);
   return retval;
}

>> Error 2 error C2440: 'type cast' : cannot convert from 'System::IntPtr'
>> to
[quoted text clipped - 23 lines]
>> >
>> > Mattias
Ben Voigt - 24 May 2007 18:37 GMT
>I have a native C++ pointer object which I need to hold in a C#
>environment,
[quoted text clipped - 6 lines]
> environment.
> But I have no clue how to do it...

An IntPtr is the right thing to use, as long as this is a native pointer,
i.e. not a pointer into a garbage collected object.  Use the ToPointer()
method to get the native pointer back.
Joachim - 25 May 2007 08:10 GMT
Only declaring an IntPtr (IntPtr myPtr;) in C# and passing it as an out
parameter to the C++ dll should work just fine then?

> >I have a native C++ pointer object which I need to hold in a C#
> >environment,
[quoted text clipped - 10 lines]
> i.e. not a pointer into a garbage collected object.  Use the ToPointer()
> method to get the native pointer back.

Rate this thread:







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.