Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

MIDL error 2258

Posted on 1999-07-02
10
Medium Priority
?
286 Views
Last Modified: 2012-06-27
Hi!

I am programming COM using c++. In my project I would like to treat ITest interfaces polimorphically the following way (only relevant lines of my IDL file are shown):
...
 interface ITest;

 [ ... ]
 interface ISample : IUnknown
 {
  [...] HRESULT GetTest([in] REFIID riid,[out,iid_is(riid),retval] ITest** Test);
 };

 [ ... ]
 interface ITest : IUnknown
 { ... };

 [ ... ]
 interface ITestChild : ITest
 { ... };

When compiling I get the following error:
error MIDL2258 : [IID_IS] may only be applied to pointers to interfaces

But if I copy the ITest interface _before_ ISample (and delete the forward declaration of it), I get no compile errors any more.

As far as I know the first (presented) syntax should also work. Or do I miss something?

Any help appreciated,
Kristof Strobl

0
Comment
Question by:kristof111897
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 2
  • 2
  • +1
10 Comments
 
LVL 1

Expert Comment

by:dd_b
ID: 1199015
write full code of IDL instead [...].
0
 

Author Comment

by:kristof111897
ID: 1199016
The full code of the IDL is:

import "oaidl.idl";
import "ocidl.idl";
      
      interface ITest;

      [
            object,
            uuid(5A281882-3070-11d3-80B0-0040F63484EC),
            helpstring("ITest Interface"),
            pointer_default(unique)
      ]
      interface ISample : IUnknown
      {
            [helpstring("method GetTest")]
            HRESULT GetTest([in] REFIID riid,[out,iid_is(riid),retval] ITest** Test);
      };

      [
            object,
            uuid(0FF30D8D-3070-11D3-80B0-0040F63484EC),
            helpstring("ITest Interface"),
            pointer_default(unique)
      ]
      interface ITest : IUnknown
      {
            [helpstring("method GetTest")]
            HRESULT GetT();
      };

      [
            object,
            uuid(5A281881-3070-11d3-80B0-0040F63484EC),
            helpstring("ITest Interface"),
            pointer_default(unique)
      ]
      interface ITestChild : ITest
      {
      };

[
      uuid(0FF30D81-3070-11D3-80B0-0040F63484EC),
      version(1.0),
      helpstring("REFIID 1.0 Type Library")
]
library REFIIDLib
{
      importlib("stdole32.tlb");
      importlib("stdole2.tlb");

      [
            uuid(0FF30D8E-3070-11D3-80B0-0040F63484EC),
            helpstring("Test Class")
      ]
      coclass Test
      {
            [default] interface ITest;
      };
};

Kristof
0
 

Expert Comment

by:Subramanya
ID: 1199017
try changing the pointer_default(unique) to following
things.
interface, pointers.
I think it will pointer_defaul(pointers) will workout.

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:kristof111897
ID: 1199018
I have already tried the 'ptr' and 'ref' with pointer_default(), but it did not help.
0
 

Expert Comment

by:Subramanya
ID: 1199019
Why don't you try with pointer_defaul(pointers).

0
 

Author Comment

by:kristof111897
ID: 1199020
There is no such thing as pointer_default(pointers).
0
 
LVL 5

Accepted Solution

by:
vachooho earned 600 total points
ID: 1199021
if you still need answer
here is it

The problem is in your interface function declaration
If you want to use REFIID [in] parameter you must
define Test [out] parameter as void ** and then cast it to
ITest*.

interface ISample : IUnknown
{
[helpstring("method GetTest")]
HRESULT GetTest([in] REFIID riid,[out,iid_is(riid),retval] void** Test);
};

This compiles without errors/warnings.

Client code:

ITest * pTest = NULL;
HRESULT hr = pSampleInterface->GetTest(IID_ITest, (void **)&pTest);

Same technique is used in IUnknown's QueryInterface() function.

What about me I will declare GetTest as following:

interface ISample : IUnknown
{
[helpstring("method GetTest")]
HRESULT GetTest([out,retval] ITest** Test);
}

This also compiled without error by MIDL compiler.

Hope, you satisfied.

If you have questions
send me mail
vachooho@yahoo.com

0
 

Author Comment

by:kristof111897
ID: 1199022
Thanks for your answer, but if the following is true

>The problem is in your interface function declaration
>If you want to use REFIID [in] parameter you must
>define Test [out] parameter as void ** and then cast it to
>ITest*.

then why does the order of the interface declaration matter? Why does the file compile without error if ITest is declared before ISample?

Also, the method you suggested

>interface ISample : IUnknown
>{
>[helpstring("method GetTest")]
>HRESULT GetTest([out,retval] ITest** Test);
>}

would require additional QI-s on the client side to determine the exact type of the interface pointer passed (e.g. ITest or ITestChild), which I do not really like.

0
 
LVL 5

Expert Comment

by:vachooho
ID: 1199023
MIDL generates proxy-stub stuff on demand -
it seems that when ITest is only forward-declared (without the body of interface, MIDL unable to generate correct marshalling code, v-table size not known) and results in error.

When you fully declare ITest before ISample - everything is clear for compiler and no error is generated.


0
 

Author Comment

by:kristof111897
ID: 1199024
Yes, that may be the case. In the sample it is easy to solve, but in my real code I can not do this (25 interfaces with circular references to them as method parameters).

But anyway - as it seams to be a MIDL "feature" - I think it is time to close this thread.

Thanks.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

662 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question