средняя ошибка MIDL2379

У нас есть библиотека C ++, и мы автоматически создаем COM-интерфейс для этой библиотеки. поэтому я автоматически сгенерировал файл IDL, и все работало нормально. Но со временем, когда к COM было добавлено больше интерфейса, мы начали получать ошибку

1> Total Format String size = 69336
1> midl : error MIDL2379: the compiler reached a limit for a format string representation. See documentation for advice.

Я получаю эту ошибку как в VS2008, так и в VS2010.

Может ли кто-нибудь помочь мне, как решить эту проблему. Я поискал по всему Интернету и не смог найти подходящего решения. Сообщается об одной ошибке в Microsoft Connect, но его статус закрыт. Они предлагают один способ решения проблемы - разделить файл IDL, что в моем случае невозможно, поскольку интерфейсы зависят друг от друга.

Я загрузил образец файла IDL SampleGenerated.idl

вот командная строка для мидл.

/W1 /nologo /char signed /env win32 /h "SampleGenerated_h.h" /tlb "Debug\SampleGenerated.tlb"

person Naveen    schedule 28.10.2013    source источник
comment
Ой. Закрытие как внешнее означает, что это не проблема VS, поэтому нам все равно, и мы закроем ее, поэтому я предполагаю, что проблема не будет устранена менее чем за 20 лет, и вам придется ее решить. Один из перечисленных здесь обходных путей - рефакторинг IDL путем распределения интерфейсов по нескольким файлам. Вы пробовали это обходное решение?   -  person sharptooth    schedule 28.10.2013
comment
Привет, @sharptooth, я не могу разделить интерфейс на несколько файлов, потому что мои интерфейсы зависят друг от друга. Например, у Interface1 может быть метод getIntergface2 (), который возвращает Interface2 *. Для этого и Interface1, и Interface2 должны быть в одном файле IDL.   -  person Naveen    schedule 28.10.2013
comment
Неужели все они настолько зависимы? Можете ли вы разделить хотя бы некоторые из них?   -  person sharptooth    schedule 28.10.2013
comment
Не совсем .. :(. Интерфейсы организованы в виде древовидной структуры. У нас есть один корневой интерфейс, из которого мы получаем несколько дочерних интерфейсов, а из этих дочерних интерфейсов снова мы можем получить больше дочерних интерфейсов и так далее .. Единственный вариант разделить будет означать изменение методов, которые возвращают указатели интерфейсов на IUnknown *. Но это снизит ясность интерфейсов, и клиентскому приложению будет сложно его использовать.   -  person Naveen    schedule 28.10.2013
comment
Что произойдет, если вы просто переместите эти интерфейсы в отдельные файлы и импортируете их в корневой файл интерфейса?   -  person sharptooth    schedule 28.10.2013
comment
Я попробую это. Это займет некоторое время .. После этого я дам вам знать результат .. Спасибо ..   -  person Naveen    schedule 28.10.2013
comment
Хорошо, что сработало !! На самом деле я предполагал, что мне может потребоваться компилировать каждый файл idl отдельно. Но создание всего моего интерфейса в виде файла IDL и их импортирование в главный файл IDL сработало (плюс я заранее объявил весь файл интерфейса в начале). Спасибо и много   -  person Naveen    schedule 28.10.2013
comment
Рад слышать, что решение было так легко.   -  person sharptooth    schedule 28.10.2013
comment
Не могли бы вы добавить ответ, подробно описывающий, как вы решили проблему?   -  person sharptooth    schedule 28.10.2013


Ответы (1)


Вот как мне это наконец удалось ...

Сначала разделите каждый интерфейс на отдельный файл IDL

Interface1.idl

Interface Interface2; // forward declaration

#ifndef __Interface1_IDL_FILE_
#define __Interface1_IDL_FILE_
import "AllIDLInterface.idl";
[
    object,
    uuid(66006A2F-B777-4e2f-A0CA-D5BE00000015),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface Interface1 : IUnknown{
HRESULT getInterface2([out, retval]Interface2** outVal )
};
#endif

Interface2.idl

Interface Interface1;// forward delcarations

#ifndef __Interface2_IDL_FILE_
#define __Interface2_IDL_FILE_
import "AllIDLInterface.idl";

[
    object,
    uuid(66006A2F-B777-4e2f-A0CA-D5BE00000015),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface Interface2 : IUnknown
{
HRESULT getInterface1([out, retval]Interface1** outVal )
};
#endif

Создайте еще один файл IDL AllInterface.idl, содержащий импорт всего файла интерфейса.

import Interface1.idl
import Interface2.idl

Теперь main.idl, для которого мы будем создавать файлы TLB

import AllInterface.idl;

Единственный недостаток здесь в том, что мы должны компилировать каждый файл IDL отдельно, если мы хотим сгенерировать файл заголовка интерфейсов C ++ / C.

person Naveen    schedule 30.10.2013