2

I am writing a wrapper around C DLL in C++/CLI so that it can be accessed in C# through a managed assembly. Using direct P/Invoke to access C functions via C# is not possible because C DLL raises exceptions which cannot be correctly caught using P/Invoke (exception message is lost when moving across C/C# boundary). So the idea is to create a managed CLI DLL which internally calls C DLL and wraps the exception to Exception class of CLI.

So the C DLL function has this declaration.

void InitDB(void **handle);

The C# app would required following declaration

void InitDB_cs(ref IntPtr handle);

To accomplish this I created C++/CLI function with following declaration

void InitDB_clr(IntPtr %handle);

However, I am unable to typecast ref InPtr into C function. I tried using following code but seems can't get the typecasting right.

void InitDB_clr(IntPtr %handle)
{
pin_ptr<IntPtr> ptr = handle.ToPointer();
InitDB(&ptr);
}

Error message for above code

error C2440: 'initializing' : cannot convert from 'void *' to 'cli::pin_ptr<Type>'
1>        with
1>        [
1>            Type=System::IntPtr
1>        ]
1>        Conversion from 'void*' to pointer to non-'void' requires an explicit cast
1>error C2664: 'InitDB' : cannot convert parameter 1 from 'cli::pin_ptr<Type> *' to 'void **'
1>        with
1>        [
1>            Type=System::IntPtr
1>        ]
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
9
  • Sorry typing error. Its InitDB (C DLL function). Thanks for bringing to my notice. Commented Jul 24, 2011 at 23:32
  • No prob. I don't know CLI, but what's the error? Does it help if you cast &ptr to void**? Commented Jul 24, 2011 at 23:33
  • I tried that but it gives me typecasting error similar to above. Commented Jul 24, 2011 at 23:41
  • Why do you declare function InitDB_clr() with the parameter handle when you never use it? Commented Jul 24, 2011 at 23:47
  • I know this is not your question, but are you sure the C++/CLI wrapper will be able to handle the exceptions? No DLL should let exceptions escape. Commented Jul 25, 2011 at 0:28

2 Answers 2

1

That's an out parameter, not really ref, correct?

Try

void InitDB_clr(IntPtr% handle)
{
    void* ptr /* = handle.ToPointer() */;
    InitDB(&ptr);
    handle = IntPtr(ptr);
}

Uncomment the initializer if it needs to be in/out.

Sign up to request clarification or add additional context in comments.

4 Comments

With the code above i get the following error when I compile in C++/CLI project: : error C2440: '=' : cannot convert from 'System::IntPtr ^' to 'System::IntPtr'
@KSingh : Don't use gcnew. By the way, this was already answered on the MSDN forums where you asked the same question.
@ildjarn: Thanks.. I cross posted on both stackoverflow and MSDN forums. And appreciate your help, it works now :)
Ugh, yeah, I was thinking of C# where it's required to use new with value types. Fixed.
0

You could use C# in an unsafe context and use

unsafe void InitDB_cs(IntPtr** handle);

1 Comment

I dont want to have pointers/unsafe code in C#. That is one of the reason for having C++/CLI managed which will have all the functions for C# and internally interacts with C DLL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.