Click here to Skip to main content
15,881,281 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Good day.

Environment: Visual Studio 2008. Language: C++

(This is evolving into a two part question, I hope that's permitted...)

I have an ATL Project that I am working to replace an existing tool developed in an older version (VC++6, I believe, although nobody seems terribly sure).

I have created the ATL service (IScribe) using the wizard and have connected to it via a console application and have been moving to a Windows Form client in order to allow me to extend the testing environment (and as a proof of concept on a future potential use for the service).

I have added to the form the :
MIDL
IIScribeServer* ISS;

and in the Form1_Load, I have the code:
MIDL
BSTR message = NULL;           //for capturing the return message from server
HRESULT hr;                    //COM error code;
hr = CoInitialize(0);
if(SUCCEEDED(hr))  //hr succ 1
{       hr = CoCreateInstance(
        CLSID_IScribeServer,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IIScribeServer,
        (void**) &ISS);
    if(SUCCEEDED(hr))  //hr succ 2
    {
        long f5 = 5;  //meaningless numbers, just proving can store and return
        long f11 = 11;
        //Call to get pseudo version information from server and display to form
        hr = ISS-> GetCaption(&f5,  &f11 , &message);

        this->Text =  gcnew System::String(message);

        message = NULL; //had a ::SysFreeString(*message), but it would fail
     } //hr succ 2
 }//hr succ 1


Question 1:
If I declare the IIScribeServer within the Form1_Load event, it works fine.
If I declare it at the Form level, as in this code, I receive "error C2440: 'type cast' cannot convert from 'cli::interior_ptr<type> to 'void**'".
What would I be missing here to allow the conversion?

As a workaround: I added an intermediary call to allow the creation
C#
BSTR message = NULL;                //used to accept return value from server.
IIScribeServer *ISSb;    //pointer to the interface
HRESULT hr;              //COM error code;


and
C#
if(SUCCEEDED(hr))  //hr succ 1
    {       hr = CoCreateInstance(
            CLSID_IScribeServer,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IIScribeServer,
            (void**) &ISSb);      //Changed HERE
if(SUCCEEDED(hr)) //hr succ 2
{

    ISX = ISXb;

    ISXb = NULL;


And all works as I expect.

In a button click on the form, I do make a call to
C#
HRESULT hr;
			LONG  puHi, puLo;
			puHi = Convert::ToInt32(this->textBoxHighPart->Text);
			puLo = Convert::ToInt32(this->textBoxLowPart->Text);
			hr = ISS ->GetTimeStamp(&puHi, &puLo);
			this->textBoxHighPart->Text = Convert::ToString((__int32)puHi);
			this->textBoxLowPart->Text = Convert::ToString((__int32)puLo);


The
C#
CoUninitialize()
is on the form close.
Which sends the values of the text box and performs minor math (add one, sub other) on them and replaces the text box. Nothing big.

This works fine and compiles in debug... but not in Release.


Question 2: Guh? I'm not sure where to start, but it doesn't build in Release.
(Q2 is SOLVED...
added a
C#
#pragma comment ( lib, "ole32.lib" ) //to link the ole32 library
at the top and that took care of it.
)

From the Output window:
1>------ Build started: Project: InfWindow, Configuration: Release Win32 ------
1>Linking...
1>InfoWindow.obj : error LNK2001: unresolved external symbol "extern "C" long __stdcall CoInitialize(void *)" (?CoInitialize@@$$J14YGJPAX@Z)
1>InfoWindow.obj : error LNK2001: unresolved external symbol "extern "C" long __stdcall CoCreateInstance(struct _GUID const &,struct IUnknown *,unsigned long,struct _GUID const &,void * *)" (?CoCreateInstance@@$$J220YGJABU_GUID@@PAUIUnknown@@K0PAPAX@Z)
1>InfoWindow.obj : error LNK2001: unresolved external symbol "extern "C" void __stdcall CoUninitialize(void)" (?CoUninitialize@@$$J10YGXXZ)
1>C:\dev\Visual Studio 2008\Projects\IScribe\Release\InfWindow.exe : fatal error LNK1120: 3 unresolved externals


(these errors occur whether the IScribeServer * ISS; is at Form level or Form1_Load level)

Had to rename the objects to IScribeServer etc... in order to not flip some wigs here, apologies if transposition errors in teh above code in making those swap outs.
Posted
Updated 15-Jul-11 7:51am
v3
Comments
Richard MacCutchan 15-Jul-11 11:04am    
Q2: Have you included Ole32.lib in your Release project settings?
stebain 15-Jul-11 13:45pm    
You, my friend, are the man.


#pragma comment( lib, "ole32.lib" )

all good.
Richard MacCutchan 15-Jul-11 13:50pm    
No problem. Sorry, I can't help with Q1.
stebain 15-Jul-11 13:52pm    
I can't complain on that! My work around seems to be sufficient, although it leaves me wary that I might be risking memory, but to my non expert eye it looks okay. How do I flag your comment for "Answer"?
Richard MacCutchan 15-Jul-11 15:21pm    
You don't. I didn't feel justified in posting my suggestion as an answer. However, feel free to add your resolution to the problem and mark as answered if you are happy with it.

 
Share this answer
 
in the interest of leaving no thread loose:

Q1) I used a work around of creating the intermediary IScribeServer object and then pointing to it and freeing that intermediary pointer.

Q2) Per Mr Richard MacCutchan, I added the Ole32.lib library to the file (using the
C#
#pragma comment( lib, "ole32.lib" )
approach. Works wonderfully. I much prefer it when it compiles in Release than continuing in debug only
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900