How do I pinvoke this function?

K

Karthik V

In a certain dll, there is this function:
typedef DWORD STDAPICALLTYPE SOMEFUNC(VOID *pHandle, IProgress
*pProgress);

where IProgress is
class IProgress { public: virtual void Update(UINT progress) = 0; };

To pinvoke this from C#, I tried the following:
[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, Progress progress);

and defined Progress as
public class Progress
{
public void Update(ushort progress)
{
// some code
}
}

Trying to invoke SomeFunc and passing an object of Progress, I get an
"Attempted to read or write protected memory" error. The other methods
in the same dll that don't involve the progress callback object (but
involve the handle parameter) work fine.

Please let me know how to pinvoke this function.
 
N

Nicholas Paldino [.NET/C# MVP]

Karthik,

I believe in this case that IProgress is not actually a class, but an
interface pointer. The thing is, while you will be able to call it in C#,
you won't be able to call the methods on the interface pointer, as it needs
to be a COM interface pointer in order to interop correctly. .NET interop
does not support native C++ interfaces.

Your P/Invoke declaration would look like this:

[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, IntPtr progress);

And the best you could do with the progress pointer is pass it around.
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
Karthik,

I believe in this case that IProgress is not actually a class, but an
interface pointer. The thing is, while you will be able to call it in C#,
you won't be able to call the methods on the interface pointer, as it
needs to be a COM interface pointer in order to interop correctly. .NET
interop

It looks like a COM interface pointer to me... or at least binary
compatible. No IUnknown or IDispatch support though.

You'll need a type library for it, and to run tlbimp.

The lack of IUnknown may cause problems.
does not support native C++ interfaces.

Your P/Invoke declaration would look like this:

[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, IntPtr progress);

And the best you could do with the progress pointer is pass it around.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Karthik V said:
In a certain dll, there is this function:
typedef DWORD STDAPICALLTYPE SOMEFUNC(VOID *pHandle, IProgress
*pProgress);

where IProgress is
class IProgress { public: virtual void Update(UINT progress) = 0; };

To pinvoke this from C#, I tried the following:
[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, Progress progress);

and defined Progress as
public class Progress
{
public void Update(ushort progress)
{
// some code
}
}

Trying to invoke SomeFunc and passing an object of Progress, I get an
"Attempted to read or write protected memory" error. The other methods
in the same dll that don't involve the progress callback object (but
involve the handle parameter) work fine.

Please let me know how to pinvoke this function.
 
N

Nicholas Paldino [.NET/C# MVP]

That's the thing, if it doesn't derive from IUnknown, then it can't
possibly be a COM interface pointer. Just because it is an interface
doesn't mean that it is supported by COM.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Karthik,

I believe in this case that IProgress is not actually a class, but an
interface pointer. The thing is, while you will be able to call it in
C#, you won't be able to call the methods on the interface pointer, as it
needs to be a COM interface pointer in order to interop correctly. .NET
interop

It looks like a COM interface pointer to me... or at least binary
compatible. No IUnknown or IDispatch support though.

You'll need a type library for it, and to run tlbimp.

The lack of IUnknown may cause problems.
does not support native C++ interfaces.

Your P/Invoke declaration would look like this:

[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, IntPtr progress);

And the best you could do with the progress pointer is pass it around.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Karthik V said:
In a certain dll, there is this function:
typedef DWORD STDAPICALLTYPE SOMEFUNC(VOID *pHandle, IProgress
*pProgress);

where IProgress is
class IProgress { public: virtual void Update(UINT progress) = 0; };

To pinvoke this from C#, I tried the following:
[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, Progress progress);

and defined Progress as
public class Progress
{
public void Update(ushort progress)
{
// some code
}
}

Trying to invoke SomeFunc and passing an object of Progress, I get an
"Attempted to read or write protected memory" error. The other methods
in the same dll that don't involve the progress callback object (but
involve the handle parameter) work fine.

Please let me know how to pinvoke this function.
 
W

Willy Denoyette [MVP]

Karthik V said:
In a certain dll, there is this function:
typedef DWORD STDAPICALLTYPE SOMEFUNC(VOID *pHandle, IProgress
*pProgress);

where IProgress is
class IProgress { public: virtual void Update(UINT progress) = 0; };

To pinvoke this from C#, I tried the following:
[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, Progress progress);

and defined Progress as
public class Progress
{
public void Update(ushort progress)
{
// some code
}
}

Trying to invoke SomeFunc and passing an object of Progress, I get an
"Attempted to read or write protected memory" error. The other methods
in the same dll that don't involve the progress callback object (but
involve the handle parameter) work fine.

Please let me know how to pinvoke this function.


It looks like IProgress is a native C++ class, you can't use such classes
directly from C#, you will have to wrap this class in a managed wrapper
using C++/CLI (VS2005 C++ using /clr option).

Willy.
 
B

Ben Voigt [C++ MVP]

Nicholas Paldino said:
That's the thing, if it doesn't derive from IUnknown, then it can't
possibly be a COM interface pointer. Just because it is an interface
doesn't mean that it is supported by COM.

COM is as much a binary standard for v-table layout as anything else, and
that interface would meet the COM binary standard.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Karthik,

I believe in this case that IProgress is not actually a class, but an
interface pointer. The thing is, while you will be able to call it in
C#, you won't be able to call the methods on the interface pointer, as
it needs to be a COM interface pointer in order to interop correctly.
.NET interop

It looks like a COM interface pointer to me... or at least binary
compatible. No IUnknown or IDispatch support though.

You'll need a type library for it, and to run tlbimp.

The lack of IUnknown may cause problems.
does not support native C++ interfaces.

Your P/Invoke declaration would look like this:

[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, IntPtr progress);

And the best you could do with the progress pointer is pass it
around.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


In a certain dll, there is this function:
typedef DWORD STDAPICALLTYPE SOMEFUNC(VOID *pHandle, IProgress
*pProgress);

where IProgress is
class IProgress { public: virtual void Update(UINT progress) = 0; };

To pinvoke this from C#, I tried the following:
[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, Progress progress);

and defined Progress as
public class Progress
{
public void Update(ushort progress)
{
// some code
}
}

Trying to invoke SomeFunc and passing an object of Progress, I get an
"Attempted to read or write protected memory" error. The other methods
in the same dll that don't involve the progress callback object (but
involve the handle parameter) work fine.

Please let me know how to pinvoke this function.
 
N

Nicholas Paldino [.NET/C# MVP]

Ben,

While that is the case, COM demands that all interfaces derive from
IUnknown. If an interface has to derive from that, then the vtable for that
interface is always going to be populated with the entries for the methods
in IUnknown in the first three slots, follwed by the methods for the
interface itself. Since the interface here doesn't derive from IUnknown,
its vtable is not going to have those entries.

There is no way that this interface could be used in COM.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
That's the thing, if it doesn't derive from IUnknown, then it can't
possibly be a COM interface pointer. Just because it is an interface
doesn't mean that it is supported by COM.

COM is as much a binary standard for v-table layout as anything else, and
that interface would meet the COM binary standard.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
in message Karthik,

I believe in this case that IProgress is not actually a class, but
an interface pointer. The thing is, while you will be able to call it
in C#, you won't be able to call the methods on the interface pointer,
as it needs to be a COM interface pointer in order to interop
correctly. .NET interop

It looks like a COM interface pointer to me... or at least binary
compatible. No IUnknown or IDispatch support though.

You'll need a type library for it, and to run tlbimp.

The lack of IUnknown may cause problems.

does not support native C++ interfaces.

Your P/Invoke declaration would look like this:

[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, IntPtr progress);

And the best you could do with the progress pointer is pass it
around.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


In a certain dll, there is this function:
typedef DWORD STDAPICALLTYPE SOMEFUNC(VOID *pHandle, IProgress
*pProgress);

where IProgress is
class IProgress { public: virtual void Update(UINT progress) = 0; };

To pinvoke this from C#, I tried the following:
[DllImport("THE_DLL.dll", SetLastError = true)]
static extern void SomeFunc(IntPtr handle, Progress progress);

and defined Progress as
public class Progress
{
public void Update(ushort progress)
{
// some code
}
}

Trying to invoke SomeFunc and passing an object of Progress, I get an
"Attempted to read or write protected memory" error. The other methods
in the same dll that don't involve the progress callback object (but
involve the handle parameter) work fine.

Please let me know how to pinvoke this function.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top