Microsoft KB Archive/814721

= BUG: You receive a &quot;TargetParameterCountException&quot; exception when you call the COM method with a Retval attribute =

Article ID: 814721

Article Last Modified on 1/18/2006

-

APPLIES TO


 * Microsoft Visual C++ .NET 2003 Standard Edition
 * Microsoft .NET Framework 1.1

-





SYMPTOMS
When dispinterface has a retval attribute in the Interface Definition Language (IDL) file of the Microsoft Component Object Model (COM) server, and when you use the Add Reference tool to import the COM server that you want to use from Microsoft Visual C++ .NET 2003 managed code, you may receive the following exception:

An unhandled exception of type 'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll Additional information:

Invalid number of parameters.



CAUSE
When you use the Add Reference tool in Visual C++ .NET 2003, the Type Library Importer (Tlbimp.exe) internally generates an interop assembly. Tlbimp.exe does not run with the /transform:dispret option.



WORKAROUND
To work around this problem, create an interop assembly manually, and then import the newly created assembly in your code. To create an interop assembly, run Tlbimp.exe with the /transform:dispret command-line option.

To do this, follow these steps:  Remove the reference to the MyServer.DLL COM component. Open a Microsoft Visual Studio .NET command prompt. Type the following command, and then press ENTER:

tlbimp /transform:dispret  /out:Interop. .dll

 In Solution Explorer, right-click Reference, and then click Add Reference. On the .NET tab, click Browse. Locate the interop .dll file that you created in step 3. Click Open, and then click OK.</li>  In the ManagedClient.cpp file, change the following code: mysrv-> GetOffsetNum(100,&i); to this: i = mysrv->GetOffsetNum(100); </li> On the Debug menu, click Start.</li></ol>

Note The .NET Framework 1.0 does not support the /transform:dispret command-line option for Ttlbimp.exe.

<div class="status_section">

STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

<div class="moreinformation_section">

Create a COM Server
<ol> Create a new file that is named MyServer.cpp in the MyServer folder.</li>  Open the MyServer.cpp file in Notepad, and then paste the following code to it:
 * 1) pragma once
 * 2) define STRICT


 * 1) ifndef _WIN32_NT
 * 2) define _WIN32_NT 0x400
 * 3) endif

using namespace ATL;
 * 1) define _ATL_ATTRIBUTES
 * 2) define _ATL_APARTMENT_THREADED
 * 3) define _ATL_NO_AUTOMATIC_NAMESPACE
 * 4) include <atlbase.h>
 * 5) include <atlcom.h>
 * 6) include <atlwin.h>
 * 7) include <atltypes.h>
 * 8) include <atlctl.h>
 * 9) include <atlhost.h>

[ module(dll, name = &quot;MyServer&quot;, helpstring = &quot;MyServer 1.0 Type Library&quot;) ]; [ emitidl ];

[  uuid(&quot;D963977F-9058-492d-9530-470C9E7B3443&quot;), dispinterface, helpstring(&quot;IMyServerObj Interface&quot;), ] __interface IMyServerObj : IDispatch {  [id(1)] HRESULT GetOffsetNum([in] int iNum,[out, retval]int* pInt); }; [  coclass, threading(&quot;apartment&quot;), vi_progid(&quot;MyServer.MyServerObj&quot;), progid(&quot;MyServer.MyServerObj.2&quot;), version(1.0), uuid(&quot;858DC2A5-444F-417e-9B5B-8D80654E1D83&quot;), helpstring(&quot;My Server class &quot;) ] class ATL_NO_VTABLE CMyServerObj : public IMyServerObj { public: CMyServerObj {  }   HRESULT GetOffsetNum(int iNum, int* pInt){ *pInt = 500; return S_OK; }  DECLARE_PROTECT_FINAL_CONSTRUCT HRESULT FinalConstruct {     return S_OK; }      void FinalRelease {  } }; </li> Save the MyServer.cpp file.</li> Open a Microsoft Visual Studio .NET command prompt.</li> Change the folder to the MyServer folder.</li> To create a COM DLL, type the following command at the command prompt:

cl /LD MyServer.cpp

A COM DLL that is named MyServer.DLL is created.</li> To register the COM DLL, type the following command at the command prompt:

regsvr32 MyServer.dll

</li></ol>

Access COM DLL from Managed Code
<ol> Start Visual Studio .NET 2003.</li> On File menu, point to New, and then click Project.</li> Under Project Types, click Visual C++ Projects. Under Templates, click Console Application (.NET). In the Name box, type ManagedClient, and then click OK.</li> In Solution Explorer, right-click Reference, and then click Add Reference.</li> On the COM tab, locate MyServer 1.0 Type Library, click Select, and then click OK.</li>  Copy the following code to ManagedClient.cpp: // This is the main project file for the Visual C++ .NET application project. // The file was generated by using an Application Wizard.


 * 1) include &quot;stdafx.h&quot;


 * 1) using <mscorlib.dll>

using namespace System; using namespace Interop; int _tmain {        MyServer::IMyServerObj *mysrv = new MyServer::CMyServerObjClass; int i = 12;

// Call the method from the COM DLL. mysrv->GetOffsetNum(100,&i); Console::WriteLine(S&quot;The new value of i is {0}&quot;,i.ToString); } </li> On Debug menu, click Start. You receive the TargetParameterCountException exception that is described in the &quot;Symptoms&quot; section of this article.</li></ol>

Additional query words: tlbimp

Keywords: kberrmsg kbbug kbpending kbcominterop KB814721

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.