Проблема с #import ..... а может и не с ним
От: KAndy Россия N/A
Дата: 16.05.04 17:42
Оценка:
Все день добрый !!!


Имеется COM-объект DataPipe (мной созданный) :

DataPipe.idl:



//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// DataPipe.idl : IDL source for DataPipe
//

// This file will be processed by the MIDL tool to
// produce the type library (DataPipe.tlb) and marshalling code.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
import "oaidl.idl";
import "ocidl.idl";
import "helper.idl"; // need ADO
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
[
    object,
    uuid(D794BDDA-4819-41C8-890E-74FA7ADB9B76),
    helpstring("IRSPipe Interface"),
    pointer_default(unique)
]
interface IRSPipe : IUnknown{
    [helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
    [helpstring("method download")] HRESULT download([in] _Recordset* rs);
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
[
    uuid(54DB464F-DA62-4DB7-9BBC-C33389FCA8B7),
    version(1.0),
    helpstring("DataPipe 1.0 Type Library")
]
library DataPipeLib
{
    importlib("stdole2.tlb");
    importlib("stdole32.tlb");
    //importlib("c:\program files\common files\system\ado\msado15.dll");  // need ADO
    [
        uuid(E655B8B0-1605-497C-BCAE-72C173F4277F),
        helpstring("RSPipe Class")
    ]
    coclass RSPipe
    {
        [default] interface IRSPipe;
    };
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////



Проблема состоит в том, что не удается воспользоваться данным объектом в другом проекте.
Каким образом необходимо подключать мой COM-объект в другой проект ???

По идее долдно быть так:

MainDlg.h :

/////////////////////////////////////////////////////////////////////////////
//
// MainDlg.h : interface of the CMainDlg class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
#import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" no_namespace rename("EOF", "adoEOF")

class CMainDlg :    public CDialogImpl<CMainDlg>,
                                    public CUpdateUI<CMainDlg>,
                                    public CMessageFilter,
                                    public CIdleHandler {
public:
    enum { IDD = IDD_MAINDLG };

        ....
        ....
        ....
        ....

};


но в таком случае две инструкции #import конфликтуют, точнее на этапе компиляции возникает многократная
ошибка вида:

c:\...\DataPipe.tlh(38) : error C2371: 'DataTypeEnum' : redefinition; different basic types
        c:\...\msado15.tlh(272) : see declaration of 'DataTypeEnum'
c:\...\DataPipe.tlh(41) : error C2371: 'PositionEnum' : redefinition; different basic types
        c:\...\msado15.tlh(377) : see declaration of 'PositionEnum'
c:\...\DataPipe.tlh(43) : error C2371: 'CursorTypeEnum' : redefinition; different basic types
        c:\...\msado15.tlh(198) : see declaration of 'CursorTypeEnum'


и так далее по всему, что объявлено в msado15.tlh


Если же вместо друх строк:

    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" no_namespace rename("EOF", "adoEOF")


оставить одну вида:

    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" rename("EOF", "adoEOF")


то возникают ошибки такие, будто не видно объявлений, которые нужны для работы с msado15.dll


Компилируется следующая комбинация:

    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" rename("EOF", "adoEOF")


но тогда компилятор считает, что рекордсет, ожидаемый методом объекта из библиотеки DataPipeLib
и рекордсет из библиотеки msado15 — совершенно разные типы данных, что меня также не устраивает.
На самом то деле это одни и те же объекты, одни и те же ADO рекордсеты.

ЧТО Я ДЕЛАЮ НЕ ТАК И КАК НАДО ???

Если у кого есть примеры, в которых продемонстрировано решение подобной задачи — буду очень прзнателен,
равно как и за другие способы решения моей проблемы.
Re: Проблема с #import ..... а может и не с ним
От: Юнусов Булат Россия  
Дата: 16.05.04 21:18
Оценка:
Здравствуйте, KAndy, Вы писали:

1 Переделай идль-ник
ADO и прочие вещи такого рода через только importlib подцепляй, по иному это моветон
Интерфейсы которые ее пользуются объявляй после импортлиба (студия почему то их порывается впихнуть раньше так что просто руками перенеси
Типа так:

import "oaidl.idl";

[
    uuid(DFEC7DCF-9823-4165-A6EF-A3E1BAC9E370),
    version(1.0)
]
library SXLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    importlib("C:\Winnt\System32\msxml.dll");
    importlib("C:\Program Files\Common Files\System\ADO\msado26.tlb");

    [
        object,
        uuid(48F84F38-6224-48F5-ACB8-45A11C6DFA22),
        dual,
        helpstring("IConverter Interface"),
        pointer_default(unique)
    ]
    interface IConverter : IDispatch
    {
        [id(1), helpstring("method StreamToXml")] HRESULT StreamToXml(
            [in] _Stream * stream, [out, retval] IXMLDOMDocument * * doc);

        [id(2), helpstring("method XmlToStream")] 
        HRESULT XmlToStream(
            [in] IXMLDOMDocument * doc, [out,retval] _Stream ** stream);
    };

    [
        uuid(812D4569-8049-4A8D-A9B1-D954FF19A047),
        helpstring("_IConverterEvents Interface")
    ]
    dispinterface _IConverterEvents
    {
        properties:
        methods:
    };

    [
        uuid(3BB0E53B-88A6-4543-A552-1A99D4FD6079),
        helpstring("Converter Class")
    ]
    coclass Converter
    {
        [default] interface IConverter;
        [default, source] dispinterface _IConverterEvents;
    };
};



2 В плюсовом коде не пиши при импорте no_namespace лучше в обьявлении методов явно указывать ADODB:: или что там еще
Re[2]: Проблема с #import ..... а может и не с ним
От: AndyCyborg Россия N/A
Дата: 17.05.04 06:46
Оценка:
Здравствуйте, Юнусов Булат, Вы писали:

Сразу скажу Большое Спасибо за столь скоро и скорее всего (еще не опробовал) очень полезную помощь!!!

Сразу вопрос сходу. В IDL файле получается есть возможность объявить интерфейс за пределами блока определения библиотеки, то есть не внутри блока

     library SXLib {
     }


а можно внутри. как это приведено в твоем примере. Так на что это влияет и что это означает. Ведь не может же быть, что определено два различных синтаксиса без всякой разницы работающих в результате. Или это совершенно эквивалентные вещи получаются ?



[skipped your code]

ЮБ>2 В плюсовом коде не пиши при импорте no_namespace лучше в обьявлении методов явно указывать ADODB:: или что там еще


Ок, спасибо. Учтем. Видимо это совет рожден чисто практикой и опытом ?


Спасибо, Булат, еще раз.
Re: Проблема с #import ..... а может и не с ним
От: Torero2002 Россия  
Дата: 17.05.04 06:51
Оценка:
Здравствуйте, KAndy, Вы писали:

KA>Все день добрый !!!



KA>Имеется COM-объект DataPipe (мной созданный) :


KA>DataPipe.idl:



KA>

KA>//////////////////////////////////////////////////////////////////////////////////////////////////////////////
KA>// DataPipe.idl : IDL source for DataPipe
KA>//

KA>// This file will be processed by the MIDL tool to
KA>// produce the type library (DataPipe.tlb) and marshalling code.

KA>//////////////////////////////////////////////////////////////////////////////////////////////////////////////
KA>import "oaidl.idl";
KA>import "ocidl.idl";
KA>import "helper.idl"; // need ADO
KA>//////////////////////////////////////////////////////////////////////////////////////////////////////////////
KA>[
KA>    object,
KA>    uuid(D794BDDA-4819-41C8-890E-74FA7ADB9B76),
KA>    helpstring("IRSPipe Interface"),
KA>    pointer_default(unique)
KA>]
KA>interface IRSPipe : IUnknown{
KA>    [helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
KA>    [helpstring("method download")] HRESULT download([in] _Recordset* rs);
KA>};
KA>//////////////////////////////////////////////////////////////////////////////////////////////////////////////
KA>[
KA>    uuid(54DB464F-DA62-4DB7-9BBC-C33389FCA8B7),
KA>    version(1.0),
KA>    helpstring("DataPipe 1.0 Type Library")
KA>]
KA>library DataPipeLib
KA>{
KA>    importlib("stdole2.tlb");
KA>    importlib("stdole32.tlb");
KA>    //importlib("c:\program files\common files\system\ado\msado15.dll");  // need ADO
KA>    [
KA>        uuid(E655B8B0-1605-497C-BCAE-72C173F4277F),
KA>        helpstring("RSPipe Class")
KA>    ]
KA>    coclass RSPipe
KA>    {
KA>        [default] interface IRSPipe;
KA>    };
KA>};
KA>//////////////////////////////////////////////////////////////////////////////////////////////////////////////
KA>



KA>Проблема состоит в том, что не удается воспользоваться данным объектом в другом проекте.

KA>Каким образом необходимо подключать мой COM-объект в другой проект ???

KA>По идее долдно быть так:


KA>MainDlg.h :


KA>
KA>/////////////////////////////////////////////////////////////////////////////
KA>//
KA>// MainDlg.h : interface of the CMainDlg class
KA>//
KA>/////////////////////////////////////////////////////////////////////////////

KA>#pragma once

KA>#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
KA>#import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" no_namespace rename("EOF", "adoEOF")

KA>class CMainDlg :    public CDialogImpl<CMainDlg>,
KA>                                    public CUpdateUI<CMainDlg>,
KA>                                    public CMessageFilter,
KA>                                    public CIdleHandler {
KA>public:
KA>    enum { IDD = IDD_MAINDLG };

KA>        ....
KA>        ....
KA>        ....
KA>        ....

KA>};
KA>


KA>но в таком случае две инструкции #import конфликтуют, точнее на этапе компиляции возникает многократная

KA>ошибка вида:

KA>
KA>c:\...\DataPipe.tlh(38) : error C2371: 'DataTypeEnum' : redefinition; different basic types
KA>        c:\...\msado15.tlh(272) : see declaration of 'DataTypeEnum'
KA>c:\...\DataPipe.tlh(41) : error C2371: 'PositionEnum' : redefinition; different basic types
KA>        c:\...\msado15.tlh(377) : see declaration of 'PositionEnum'
KA>c:\...\DataPipe.tlh(43) : error C2371: 'CursorTypeEnum' : redefinition; different basic types
KA>        c:\...\msado15.tlh(198) : see declaration of 'CursorTypeEnum'
KA>


KA> и так далее по всему, что объявлено в msado15.tlh



KA>Если же вместо друх строк:


KA>
KA>    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
KA>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" no_namespace rename("EOF", "adoEOF")
KA>


KA> оставить одну вида:


KA>
KA>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" rename("EOF", "adoEOF")
KA>


KA> то возникают ошибки такие, будто не видно объявлений, которые нужны для работы с msado15.dll



KA>Компилируется следующая комбинация:


KA>
KA>    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
KA>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" rename("EOF", "adoEOF")
KA>


KA> но тогда компилятор считает, что рекордсет, ожидаемый методом объекта из библиотеки DataPipeLib

KA> и рекордсет из библиотеки msado15 — совершенно разные типы данных, что меня также не устраивает.
KA> На самом то деле это одни и те же объекты, одни и те же ADO рекордсеты.

KA> ЧТО Я ДЕЛАЮ НЕ ТАК И КАК НАДО ???


KA> Если у кого есть примеры, в которых продемонстрировано решение подобной задачи — буду очень прзнателен,

KA> равно как и за другие способы решения моей проблемы.


Лучше вачсего таким образом:

#import "libid:EF53050B-882E-4776-B643-EDA472E8E3F2" version("2.7")


Тогда не придется использовать прямые пути.
Smart? Prove it!
Re: Проблема с #import ..... а может и не с ним
От: Vi2 Удмуртия http://www.adem.ru
Дата: 17.05.04 07:35
Оценка: 8 (1)
Здравствуйте, KAndy, Вы писали:

Дело в том, что import и importlib работают в паре. Т.е. есть две последовательности определения интерфейсов (или других типов):
1. import...interface...importlib. Пример

import "msado15.idl";  // need ADO
...
interface Ixxx : IDispatch {
...
    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
...
library XXXLib
{
...
importlib("x:\program files\common files\system\ado\msado15.dll");  // need ADO

msado15.idl определяет тип _Recordset в определении типа Ixxx и маршаллируется с помощью msado15.dll

Здесь, очевидно, есть трудности. Наверное, это ошибка в MIDLе (или еще где), что интерфейс семантически разбирается до его использования в блоке library, в котором и определяется тип из некоей TLB. Но ничего не поделаешь

2. importlib...interface
library XXXLib
{
...
importlib("x:\program files\common files\system\ado\msado15.dll");  // need ADO
...
interface Ixxx : IDispatch {
...
    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);

msado15.dll определяет тип _Recordset в определении типа Ixxx и маршаллируется с помощью msado15.dll


KA>но в таком случае две инструкции #import конфликтуют, точнее на этапе компиляции возникает многократная
KA>Если же вместо друх строк:

KA>    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
KA>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" no_namespace rename("EOF", "adoEOF")

KA> оставить одну вида:
KA>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" rename("EOF", "adoEOF")

KA> то возникают ошибки такие, будто не видно объявлений, которые нужны для работы с msado15.dll

Это происходит потому, что твой IDL присваивает определения тех данных, которые упоминаются в нем (например, _Recordset) и не определяет тех, которые в нем не упоминаются. Это если не указано importlib. MIDLу просто напросто неоткуда брать информацию о таких типах, он и включает их в создаваемую TLB. OLE View показывает это хорошо, да и #import тоже.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[2]: Проблема с #import ..... а может и не с ним
От: AndyCyborg Россия N/A
Дата: 17.05.04 09:40
Оценка:
Здравствуйте, Vi2, Вы писали:

День добрый. Приятен и вместе с тем обнадеживает тот факт, что к проблеме прикоснулись Уважаемые и Почтенные люди здешних мест. Спасибо !

Я потратил некоторое время на решение этой делемы до обращения с вопросом в форум. Вообще странно: впечатление, будто до меня ранее никто в это г... не наступал. Ладно, это лирика.

Вот что интересно. Предложенная в нижеследующем примере инструкция

Vi2>import "msado15.idl";  // need ADO


самим microsoft не рекомендуется. Вернее ... может не во всех случаях это нерабочий вариант, но если в проекте будет генериться прокси/стаб объект, то это точно не скомпилится. Нужно действовать через некий файл посредник. Они (MS_guys) это делают вот как:

import "oaidl.idl";
import "ocidl.idl";
import "helper.idl";    // import ADO thru helper IDL file


Теперь что из себя представляет "helper.idl". А это вот что:

import "msado15.idl";


И все. Но ...... нужен еще один файлик. Вот этот — helper.h:

#ifndef HELPER_H
#define HELPER_H

struct _Recordset;

    #if !defined(__cplusplus) || defined(CINTERFACE)
        typedef struct _Recordset _Recordset;
    #endif

#endif


Как видно, он исполнен в стиле VC 6.0, но это не важно. Важно, что они сами используют и рекомендуют именно такую технику. Вот собсна Было бы просто суппер, если бы все эти хитрые штучки были бы собраны однажды в одном месте, а не вот так с потом и кровью собирались каждым. Это взято из рекомендуемого ими же примера, который называется Atl2ado и может быть скачан с ms-сайта.

Кстати там же (в этом проекте) есть небольшой .txt, комментирующий происходящее, и вот что там в частности написано:



ATL2ADO.exe is a sample that demonstrates how to create a simple ATL COM object
that returns a disconnected ADO recordset. The sample also includes a Visual
Basic client that uses the ADO _Recordset returned from the ATL COM Server. The
Visual Basic client can change the record data and use the UpdateBat method
provided by the server to save changes to the database. After extracting the
files, build the Visual C++ project first to register the COM Objects, and then
use Visual Basic 6.0 to build the client program. The client and server can be
distributed to different computers on the network.

ATL2ADO.exe is a sample that demonstrates a minimal three-tiered Database
Application using ADO 2.0. An ATL server in the middle tier returns a read/write
disconnected recordset to a Visual Basic client for presentation. The Visual
Basic client can change the data and send it to the server to be updated. The
business logic is located in the COM server. The ATL COM server then updates the
Database tier.

The sample also shows how to build the proxy/stub DLL that is used to marshal the
recordset. The sample includes an Access .mdb file that you can use with Access
and SQL to build the student table that you can use with SQL Server. Use the
following query with the GradYear parameter supplied by the Visual Basic client:
"SELECT * FROM Student WHERE GradYear > ?"

Build the Visual C++ project with Visual C++ 6.0. This will create and register
the server and the proxy/stub dll. Build the Visual Basic project with Visual
Basic version 6.0. You can build the server on one computer and the client on
another computer on the same network. Copy the included Access database:
ADOSTUDENT.MDB to c:\test (or change the connection string in the source file).

The sample server was created with the ATL COM AppWizard as an .exe server. A
simple object ( r1DisRS ) was inserted. The following additions were made to the
.idl file:

1. Import helper.idl. The file name "helper.idl" is arbitrary. "helper.idl"
consists of one line: import msado15.idl. You must import ADO indirectly to
successfully build the proxy/stub DLL. Otherwise, MIDL gives you compiler
errors.

2. Add the following three methods to the interface:
getRS([in,optional,defaultvalue(88)] short GY, [out, retval]_Recordset **ppRS);
ConnString([in] BSTR newVal);
UpdateBat( _Recordset *ppRS);

3. In the Library section of the .idl, import the ADO DLL.

You must also create a file helper.h with the following contents:

struct _Recordset;
#if !defined(__cplusplus) || defined(CINTERFACE)
typedef struct _Recordset _Recordset;
#endif

ADO is imported thru the file stdAfx.h with the following two lines:

#undef EOF // Necessary for EOF collision.
#import "msado15.dll" no_namespace // Correct place to import ADO.




Это не все, а лишь, как мне показалось, относящийся к проблеме отрывок.



Vi2>Здравствуйте, KAndy, Вы писали:


Vi2>Дело в том, что import и importlib работают в паре. Т.е. есть две последовательности определения интерфейсов (или других типов):

Vi2>1. import...interface...importlib. Пример


Я вот не сомневаюсь в этих словах, но где описано это, что именно такая последовательность и такая связка. г_д_е э_т_о н_а_п_и_с_а_н_о ??? Книжка, ссылка, статья — хотел бы я очень то писание прочесть.


Vi2>
Vi2>import "msado15.idl";  // need ADO
Vi2>...
Vi2>interface Ixxx : IDispatch {
Vi2>...
Vi2>    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
Vi2>...
Vi2>library XXXLib
Vi2>{
Vi2>...
Vi2>importlib("x:\program files\common files\system\ado\msado15.dll");  // need ADO
Vi2>

Vi2>msado15.idl определяет тип _Recordset в определении типа Ixxx и маршаллируется с помощью msado15.dll

Vi2>Здесь, очевидно, есть трудности. Наверное, это ошибка в MIDLе (или еще где), что интерфейс семантически разбирается до его использования в блоке library, в котором и определяется тип из некоей TLB. Но ничего не поделаешь



Да, это очень драматичное рассуждение !



Vi2>2. importlib...interface

Vi2>
Vi2>library XXXLib
Vi2>{
Vi2>...
Vi2>importlib("x:\program files\common files\system\ado\msado15.dll");  // need ADO
Vi2>...
Vi2>interface Ixxx : IDispatch {
Vi2>...
Vi2>    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
Vi2>

Vi2>msado15.dll определяет тип _Recordset в определении типа Ixxx и маршаллируется с помощью msado15.dll
Vi2>

Vi2>

KA>>но в таком случае две инструкции #import конфликтуют, точнее на этапе компиляции возникает многократная
KA>>Если же вместо друх строк:
Vi2>

KA>>    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
KA>>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" no_namespace rename("EOF", "adoEOF")
Vi2>

KA>> оставить одну вида:
Vi2>
KA>>    #import "C:\Prog\SQL_XP\DataPipe\Debug\DataPipe.dll" rename("EOF", "adoEOF")
Vi2>

KA>> то возникают ошибки такие, будто не видно объявлений, которые нужны для работы с msado15.dll

Vi2>Это происходит потому, что твой IDL присваивает определения тех данных, которые упоминаются в нем (например, _Recordset) и не определяет тех, которые в нем не упоминаются. Это если не указано importlib. MIDLу просто напросто неоткуда брать информацию о таких типах, он и включает их в создаваемую TLB. OLE View показывает это хорошо, да и #import тоже.


Хорошо, пусть он их не включает и ему их не хватает. Но если оставить строку

#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")


то тут же получаем множественную ошибку связанную с повторным определением типов. Я вроде писал об этом в первом свое посте. Вот меня что смущается то на самом деле.

Какая-то странная ситуация. Вся странность ... видимо произрастает из не полного понимания того, что, куда и когда включается, а что нет.
Вот если в своем IDL файле я включаю через import и через importlib файлы, относящиеся к ado, то нужно ли мне потом в других проектах, где подключаю _свой_ COM-объект, также импортить адошные либы ??? Ведь в мой они по идее уже включены или я сурово заблуждаюсь ??? Где, где все это расписано ? Есть такие книги ? В MSDN что-то я не обнаружил исчерпывающих объяснений — может хреново искал ?
Проблема с #import ..... а может и не с ним
От: Vi2 Удмуртия http://www.adem.ru
Дата: 17.05.04 11:25
Оценка: 10 (1)
#Имя: FAQ.com.import.library
Здравствуйте, AndyCyborg, Вы писали:

Я с проблемами с ADO не сталкивался, поэтому и не сразу написал.

Итак, IDL файл необходим для определения интерфейсов, что следует из аббревиатуры. Однако он сам используется редко, чаще используется его бинарный эквивалент в виде TLB файла. А также он может быть использован для генерации кода прокси/стаб DLLки.

Дело немного осложняется тем, что раньше до IDL файла был ODL файл, имеющий немного другой смысл и трактовку, но который наложил отпечаток на разбор IDL файла: ODL файл имел блок [library], в котором описывались интерфейсы всех объектов. Эти интерфейсы были дисп-интерфейсами и не требовали кодов маршаллинга, ибо использовался стандартный маршаллер по TLB файлу.

IDL файл стал расширением ODL, поэтому, наверное, и решили, что интерфейсы внутри блок [library] не требуют маршаллинга, в то время как вне его требуют. MSDN говорит об этом в "Generating a Type Library with MIDL" и "Generating a Proxy DLL and a Type Library from a Single IDL File" (ODL и IDL можно считать синонимами в этом контексте).

1. Итак, первое решение:
library XXXLib {
...
importlib("x:\program files\common files\system\ado\msado15.dll");  // определение _Recordset
...
interface Ixxx : IDispatch {
...
    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);

Для интерфейса Ixxx не будет генерится коды custom маршаллинга и, следовательно, нужно использовать только TLB маршаллер. Т.е. интерфейс должен быть OLE совестимым и иметь атрибут oleautomation.

2. Если нужна своя прокси DLL, то это решение не подходит. Нужно выносить определения интерфейсов вовне блока [library]:
interface Ixxx : IDispatch {
...
    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
...
library XXXLib {
...
importlib("x:\program files\common files\system\ado\msado15.dll");  // определение _Recordset
...
interface Ixxx; // или как-то еще...

Однако это не компилится, потому что, как я раньше писал, MIDL имеет в этом месте проблему — _Recordset в месте определения интерфейса Ixxx еще не определен.

3. Можно было бы обойти через forward declaration интерфейса _Recordset
interface _Recordset; // forward declaration
interface Ixxx : IDispatch {
...
    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
...
library XXXLib {
...
importlib("x:\program files\common files\system\ado\msado15.dll");  // определение _Recordset
...
interface Ixxx; // или как-то еще...

Однако это также не проходит, потому что _Recordset должен принадлежать текущему файлу (или по другой причине). Может быть пройдет вариант точного описания типа ADODB._Recordset, но у меня это не прошло.

4. Нужно искать вариант замены forward declaration. Для твоего случая есть файл msado15.idl, который мы и импортируем для определения интерфейсов. Если такого idlа нет, то нужно к следующему шагу перейти.
import "msado15.idl"; // определение _Recordset
interface Ixxx : IDispatch {
...
    [id(2),helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
...
library XXXLib {
...
importlib("x:\program files\common files\system\ado\msado15.dll");  // определение _Recordset
...
interface Ixxx; // или как-то еще...

Все бы хорошо, но директива import генерит в h файле строчку #include "msado15.h", которая приводит к ошибке работы компилятора всего проекта, потому что MS не предоставила этот файл для своих пользователей.

5. Итак, создаем свой IDL файл, для которого создадим пресловутый h файл, который и позволит компиляцию проекта. В нем можно использовать конструкции, которые определяют интерфейсы _Recordset и другие. Или вставить директиву #import "msado15.dll" no_namespace // Correct place to import ADO.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[4]: Проблема с #import ..... а может и не с ним
От: AndyCyborg Россия N/A
Дата: 17.05.04 12:07
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, AndyCyborg, Вы писали:


Vi2>Я с проблемами с ADO не сталкивался, поэтому и не сразу написал.


Мда. А почему я так откровенно с ними столкнулся. Может я чего-то не того ???

[skipped тонна кода]


Vi2>Все бы хорошо, но директива import генерит в h файле строчку #include "msado15.h", которая приводит к ошибке работы компилятора всего проекта, потому что MS не предоставила этот файл для своих пользователей.


Vi2>5. Итак, создаем свой IDL файл, для которого создадим пресловутый h файл, который и позволит компиляцию проекта. В нем можно использовать конструкции, которые определяют интерфейсы _Recordset и другие. Или вставить директиву #import "msado15.dll" no_namespace // Correct place to import ADO.


Простите за возможнно чрезмерное красноречие, но хочется после этой террады сказать


"НУ НИХЕРА СЕБЕ ИМПОРТНУЛИ БИБЛИОТЕЧКУ !!!"


А почему все так сложно ???
Тут же возникает мысль: "К такому сэксу все уже давно, пишущие в этой среде, давно привыкли, или это я пошел какими-то дебрями ???" Вот теперь какие меня сомнения терзают жутко. Или у меня неправильная шкала оценки сложности ? Или .... короче я просто теряюсь. Жуть какая-то.

А за такоео обстоятельно разъяснение Безмерное Спасибо !!! Буду просветляться и вчитываться в упомянутые манускрипты.
Re: Проблема с #import ..... а может и не с ним
От: Tom Россия http://www.RSDN.ru
Дата: 17.05.04 12:29
Оценка:
Что то ты намудрил. Вот пример который компилируется.


import "oaidl.idl";
import "ocidl.idl";
import "msado15.idl";

[
    object,
    uuid(D8C046AA-7EEC-4FA1-94B9-6DDC1B21764B),

    helpstring("ILabudaDuda Interface"),
    pointer_default(unique)
]
interface ILabudaDuda : IUnknown
{
    [helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
};

[
    uuid(E95CBE9F-5CF7-419D-85F9-782F041288ED),
    version(1.0),
    helpstring("T1212 1.0 Type Library")
]
library T1212Lib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");
        // Не надо тут делать importlib, так как уже сделали #import
    
    [
        uuid(EE879B08-32AA-478F-A2B3-518550C666C1),
        helpstring("LabudaDuda Class")
    ]
    coclass LabudaDuda
    {
        [default] interface ILabudaDuda;
    };
};



другой проект:
// stdafx.h : include file for standard system include files,
//      or project specific include files that are used frequently,
//      but are changed infrequently

#if !defined(AFX_STDAFX_H__B173B71C_37B7_4166_9B4D_A26FDE2EAC6D__INCLUDED_)
#define AFX_STDAFX_H__B173B71C_37B7_4166_9B4D_A26FDE2EAC6D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED

#include <atlbase.h>
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include <atlcom.h>

#import "D:\\Projects\\T1212\\Debug\\T1212.dll" no_namespace rename("EOF", "adoEOF")

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__B173B71C_37B7_4166_9B4D_A26FDE2EAC6D__INCLUDED)
Народная мудрось
всем все никому ничего(с).
Re[5]: Проблема с #import ..... а может и не с ним
От: Vi2 Удмуртия http://www.adem.ru
Дата: 17.05.04 12:52
Оценка:
Здравствуйте, AndyCyborg, Вы писали:

AC>А почему все так сложно ???

Я не знаю. Достаточно было поставлять с системой файл msado15.h

AC>Тут же возникает мысль: "К такому сэксу все уже давно, пишущие в этой среде, давно привыкли, или это я пошел какими-то дебрями ???" Вот теперь какие меня сомнения терзают жутко. Или у меня неправильная шкала оценки сложности ? Или .... короче я просто теряюсь. Жуть какая-то.

Если откровенно, то меня тоже стали терзать жутко.

Но, заменив _Recordset на IDispatch или VARIANT, ты не вляпался бы в это, проиграв в явном описании интерфейса. (Кстати, некоторые уважаемые программы ТАК и делают). Или не делать свой маршаллер. Или переходить на Net.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Проблема с #import ..... а может и не с ним
От: AndyCyborg Россия N/A
Дата: 17.05.04 13:14
Оценка:
Здравствуйте, Vi2, Вы писали:

Vi2>Здравствуйте, AndyCyborg, Вы писали:


Vi2>

AC>>А почему все так сложно ???

Vi2>Я не знаю. Достаточно было поставлять с системой файл msado15.h
Vi2>

Мда, и првда что ли ..... ;(

AC>>Тут же возникает мысль: "К такому сэксу все уже давно, пишущие в этой среде, давно привыкли, или это я пошел какими-то дебрями ???" Вот теперь какие меня сомнения терзают жутко. Или у меня неправильная шкала оценки сложности ? Или .... короче я просто теряюсь. Жуть какая-то.

Vi2>Если откровенно, то меня тоже стали терзать жутко.

Стали! Значит было время, что нормальным казалось? Ну это так, реплика в пустоту в принципе не нуждающаяся в ответе


Vi2>Но, заменив _Recordset на IDispatch или VARIANT, ты не вляпался бы в это, проиграв в явном описании интерфейса.


Ну да, верно. Теперь я это понял. Спасибо !


(Кстати, некоторые уважаемые программы ТАК и делают). Или не делать свой маршаллер. Или переходить на Net.

Шикарно! НЕ в бровь а в глаз. Просто у меня в бэкграунде в мозу постоянно эта мысля крутится и приоритет ее повышается всякий раз, когда я наступаю в очердную ... лепешку от MS. Ведь таких вещей оооочень много.
Но примерять на себя .net пока не хочу, если только по мере суровой необхоидмости. Тесно мне в нем что ли. А с другой стороны это все же мэйнстрим, то есть против ветра мудрые люди стараются не .... не плыть. Тогда лучше быстрее прыгнуть в эту воду, чем долго стоять на берегу и боязливо сувать туда ногу

НоНеХооооочицааааааа ((
Re[2]: Проблема с #import ..... а может и не с ним
От: AndyCyborg Россия N/A
Дата: 17.05.04 13:32
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Что то ты намудрил. Вот пример который компилируется.


Возможно, но хотелось бы доказательств

Сразу оговорюсь, что компиляция еще не признак .... ну факт, думаю. известный.
Хотя в моем случае первоначальном я и до успшной компиляции не добирался.

В приведенном ниже коде не все есть, что нужно.

Без importlib_а и правда компилится, но проблемы должны возникнуть позже.

import "msado15.idl"; — тоже не рекомендовано. Причем в моем проекте компилировалась proxy/stub. Так при таком прямом включении вообще проект не компилился, в то время как ты утверждаешь, что все тип-топ.

И еще, цитата из конца кода, приведенного ниже.

Tom>#import "D:\\Projects\\T1212\\Debug\\T1212.dll" no_namespace rename("EOF", "adoEOF")


этого тоже мало. Теперь надо определить объект нашей библиотеки и поработать с адошными объектами, чтобы появились обращения/ссылки на типы и из нашей, и из адошной библы. Если при всех этих условиях все будет будет successful — вот тогда будет все просто замечательно. Но у меня так не вышло. Думаю, что и у Vi2 тоже такого коммунизма не наступило.

В любом случае спасибо за участие в решении проблемы !









Tom>
Tom>import "oaidl.idl";
Tom>import "ocidl.idl";
Tom>import "msado15.idl";

Tom>[
Tom>    object,
Tom>    uuid(D8C046AA-7EEC-4FA1-94B9-6DDC1B21764B),

Tom>    helpstring("ILabudaDuda Interface"),
Tom>    pointer_default(unique)
Tom>]
Tom>interface ILabudaDuda : IUnknown
Tom>{
Tom>    [helpstring("method upload")] HRESULT upload([in] _Recordset* rs);
Tom>};

Tom>[
Tom>    uuid(E95CBE9F-5CF7-419D-85F9-782F041288ED),
Tom>    version(1.0),
Tom>    helpstring("T1212 1.0 Type Library")
Tom>]
Tom>library T1212Lib
Tom>{
Tom>    importlib("stdole32.tlb");
Tom>    importlib("stdole2.tlb");
Tom>        // Не надо тут делать importlib, так как уже сделали #import
    
Tom>    [
Tom>        uuid(EE879B08-32AA-478F-A2B3-518550C666C1),
Tom>        helpstring("LabudaDuda Class")
Tom>    ]
Tom>    coclass LabudaDuda
Tom>    {
Tom>        [default] interface ILabudaDuda;
Tom>    };
Tom>};
Tom>



Tom>другой проект:

Tom>
Tom>// stdafx.h : include file for standard system include files,
Tom>//      or project specific include files that are used frequently,
Tom>//      but are changed infrequently

Tom>#if !defined(AFX_STDAFX_H__B173B71C_37B7_4166_9B4D_A26FDE2EAC6D__INCLUDED_)
Tom>#define AFX_STDAFX_H__B173B71C_37B7_4166_9B4D_A26FDE2EAC6D__INCLUDED_

Tom>#if _MSC_VER > 1000
Tom>#pragma once
Tom>#endif // _MSC_VER > 1000

Tom>#define STRICT
Tom>#ifndef _WIN32_WINNT
Tom>#define _WIN32_WINNT 0x0400
Tom>#endif
Tom>#define _ATL_APARTMENT_THREADED

Tom>#include <atlbase.h>
Tom>//You may derive a class from CComModule and use it if you want to override
Tom>//something, but do not change the name of _Module
Tom>extern CComModule _Module;
Tom>#include <atlcom.h>

Tom>#import "D:\\Projects\\T1212\\Debug\\T1212.dll" no_namespace rename("EOF", "adoEOF")

Tom>//{{AFX_INSERT_LOCATION}}
Tom>// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

Tom>#endif // !defined(AFX_STDAFX_H__B173B71C_37B7_4166_9B4D_A26FDE2EAC6D__INCLUDED)
Tom>
Re[2]: Проблема с #import ..... а может и не с ним
От: Юнусов Булат Россия  
Дата: 18.05.04 06:39
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>Что то ты намудрил. Вот пример который компилируется.



TTom> // Не надо тут делать importlib, так как уже сделали #import

Если не делать importlib то адошные определения будут в твоем ком сервере торчать (что совершенно излишне) — попробуй посмотреть через import или tlb2h
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.