By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,215 Members | 1,920 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,215 IT Pros & Developers. It's quick & easy.

[Q] Interop: Pointer to structure in interface method

P: n/a
I have COM-object with Iface interface:

typedef struct
{
....
} TStruct;

[
object,
uuid(...)
pointer_default(unique),
local
]
interface Iface : IUnknown
{
TStruct* getDataPtr();
}

Question: how can i use this object in .Net?

For wrappers

[StructLayout(LayoutKind.Sequential)]
public struct TStruct
{
....
}

[Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]
public interface Iface
{
TStruct getDataPtr();
}

Tlbexp output is following:

[
odl,
uuid(...),
version(1.0),
oleautomation,
custom(..., ...)

]
interface Iface : IUnknown {
HRESULT _stdcall getDataPtr([out, retval] TStruct * pRetVal);
};

Many Thanks!

Aug 15 '07 #1
Share this Question
Share on Google+
1 Reply


P: n/a
That's a poorly defined COM interface. Aside from the AddRef and
Release methods on the IUnknown interface, COM interfaces are supposed to
return an HRESULT. Return values are supposed to be passed through
parameters with the out and retval attributes applied to them.

The TLBIMP program is expecting this.

You are going to have to define this interface yourself in code, like
so:

[Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]
[PreserveSig]
public interface Iface
{
IntPtr getDataPtr();
}

Notice the addition of the PreserveSig attribute, as well as the
returning of an IntPtr (since you are returning a pointer in your code).

Once you get the IntPtr, you can call the static PtrToStructure method
on the Marshal class to get the structure returned.

After you do that, you should pass the IntPtr to the static
FreeCoTaskMem method on the Marshal class, to de-allocate the memory
allocated in the implementation of the getDataPtr method. COM dictates that
you have to allocate memory locations that are passed around through the
IMalloc interface (which is wrapped up in the utility function
CoTaskMemAlloc). If you are not allocating the memory that is returned with
this function, then that's another error in the implementation.

Your COM interface should really be defined like this:

[
object,
uuid(...)
pointer_default(unique),
local
]
interface IFace : IUnknown
{
HRESULT GetDataPtr([in, out] TStruct *struct);
}

This requires the structure to be allocated by the caller. All you have
to do is check to make sure that the pointer is not null in your code, and
then set the values on the structure passed in. Then, your .NET code will
work correctly.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

<ya*****@gmail.comwrote in message
news:11**********************@57g2000hsv.googlegro ups.com...
>I have COM-object with Iface interface:

typedef struct
{
...
} TStruct;

[
object,
uuid(...)
pointer_default(unique),
local
]
interface Iface : IUnknown
{
TStruct* getDataPtr();
}

Question: how can i use this object in .Net?

For wrappers

[StructLayout(LayoutKind.Sequential)]
public struct TStruct
{
...
}

[Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]
public interface Iface
{
TStruct getDataPtr();
}

Tlbexp output is following:

[
odl,
uuid(...),
version(1.0),
oleautomation,
custom(..., ...)

]
interface Iface : IUnknown {
HRESULT _stdcall getDataPtr([out, retval] TStruct * pRetVal);
};

Many Thanks!

Aug 15 '07 #2

This discussion thread is closed

Replies have been disabled for this discussion.