powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / (COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
25 сообщений из 33, страница 1 из 2
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521386
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используем Fax Service Extended COM
Задача: объединить в один факс несколько документов
IFaxDocument2::Bodies property
и послать используя
IFaxDocument2::ConnectedSubmit2 method
При этом намеренно подсовываем некорректный документ (например .wav), и хотим узнать индекс паршивого документа (чтобы понять какой именно документ вышиб ф-цию).
Метод ConnectedSubmit2 (ссылка выше) нам такую возможность вроде как предоставляет, ниже оригинал из MSDN.
Код: plaintext
1.
2.
3.
4.
5.
HRESULT ConnectedSubmit2(
  [in]           IFaxServer *pFaxServer,
  [out]          VARIANT *pvFaxOutgoingJobIDs,
  [out, retval]  LONG *plErrorBodyFile
);


plErrorBodyFile [out, retval]Type: LONG*
A LONG representing the zero-based position of the submitted file that caused the fax send operation to fail. .
To illustrate plErrorBodyFile, here is an example: The following list of files is submitted as the value of IFaxDocument2::Bodies:
"MyTextFile.txt;AnotherTextFile.txt;MyPDFfile.pdf;MyWordFile.doc".
Because the "*.pdf" extension is not supported, the send operation will fail and plErrorBodyFile will return as 2.

Рисуем простенький код Vb.Net (С# фактически тоже самое, лазил в пример SDK) с заложенной ошибкой:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
  Private Sub ButtonSendFax_Click(sender As Object, e As EventArgs) Handles ButtonSendFax.Click
    Dim objFaxServer As New FAXCOMEXLib.FaxServer
    Dim objFaxDocument As New FAXCOMEXLib.FaxDocument

    Dim iErrorIndex As Integer
    Try
      objFaxServer.Connect("")
      With objFaxDocument
        Dim bodies(2) As String
        bodies(0) = "C:\111\test_txt.txt"
        bodies(1) = "C:\111\win8.tif"
        bodies(2) = "C:\111\greet1.wav"
        .Bodies = bodies
        .Recipients.Add("500")
        .Sender.LoadDefaultSender()

        'send
        Dim strJobIds As Object = Nothing
        iErrorIndex = .ConnectedSubmit2(objFaxServer, strJobIds)
        Dim strArrJobIds As String() = strJobIds
        MsgBox(strArrJobIds(0))
      End With
    Catch ex As Exception
      MsgBox(ex.Message)
    End Try

    Try : objFaxServer.Disconnect() : Catch : End Try
  End Sub



И вот здесь нестыковка.
Вот что есть в Interop:
Код: vbnet
1.
2.
Function ConnectedSubmit2(pFaxServer As FAXCOMEXLib.IFaxServer, ByRef pvFaxOutgoingJobIDs As Object) As Integer
 'является членом: FAXCOMEXLib.IFaxDocument2


Вот такая чушь в VB.Net примере SDK Win7 (такая же для C#):
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
     Dim iErrorIndex As Integer
      iErrorIndex = objFaxDoc.ConnectedSubmit2(objFaxServer, strJobIds)
      If (iErrorIndex <> -1) Then
        System.Console.Write("ConnectedSubmit2 failed ErrorIndex = ")
        System.Console.Write(iErrorIndex)
        System.Console.WriteLine()
        bRetVal = False
        GoTo ExitFun
      End If
...
    Catch excep As Exception
      System.Console.WriteLine("Exception Occured")
      System.Console.WriteLine(excep.Message)
      MsgBox(iErrorIndex)
    End Try


Ну т.е. по логике iErrorIndex это и есть plErrorBodyFile,
да, если все хорошо, то iErrorIndex возвращает "-1" - нет "бракованных" файлов
Но если плохо, то вываливаемся по Exeption
"Operation failed" -и на этом все.
Т.е. ничего кроме -1 в случае успеха эта хрень в принципе вернуть не может.
Вопрос понятен: что я должен сделать с кодом чтобы получить plErrorBodyFile?

Для сравнения C++ код, тот же SDK пример (простыня, не хотелось бы с этим связываться, делал один раз в VB6 CoCreateInstance, но это "нечто") выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
               //initialize COM
                hr = CoInitialize(NULL);
                if(FAILED(hr))
                {
                        //failed to init com
                        _tprintf(_T("Failed to init com. Error %x \n"), hr);
                        bRetVal = false;
                        goto Exit;
                }

                hr = CoCreateInstance (CLSID_FaxServer, 
                            NULL, 
                            CLSCTX_ALL, 
                            __uuidof(IFaxServer), 
                            (void **)&pFaxServer);
...
                VARIANT jobIds;
                hr = pFaxDoc->ConnectedSubmit2(pFaxServer, &jobIds, &lErrorBodyFile);
                if (FAILED(hr) || (-1 != lErrorBodyFile))
                {
                        _tprintf(_T("ConnectedSubmit2 failed. Error %x \n"), hr);
                        _tprintf(_T("Error Index File %d \n"), lErrorBodyFile);
                        bRetVal = false;
                        goto Exit;
                }
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521543
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, но это фигня какая-то
C++ тест пример из SDK этот момент нормально отрабатывает:

Код: vbnet
1.
2.
3.
C:\Setup\Tests\SDK\sendfax\cpp\Debug>SendFax.exe /n 500 /d "C:\111\test_txt.txt;C:\111\win8.tif;C:\111\greet1.wav"
ConnectedSubmit2 failed. Error 80070483
Error Index File 2


А как этот plErrorBodyFile вытянуть из
Код: vbnet
1.
2.
Function ConnectedSubmit2(pFaxServer As FAXCOMEXLib.IFaxServer, ByRef pvFaxOutgoingJobIDs As Object) As Integer
 'является членом: FAXCOMEXLib.IFaxDocument2


я не понимаю.
Потому что если она валится в Exeption, то понятно что уже ничего не вернет.
Т.е. какая курица так сделала и почему так?

Если не удастся понять и как-то извлечь номер файла из VB-кода, то видится только один относит. простой вариант:
в случае возврата этой ошибки в VB.Net (Operation Failed==80070483==-2147023741)
запускать консольное приложение C++ с теми же исх. параметрами (файлами)
А консольное приложение сделать так:
переработать SDK Sample так чтобы он возвращал индекс файла в качестве Error Level (ExitCode).

Ну либо оформить как Dll и вызов через API, либо полностью делегировать эту ф-цию в C++, но это умучаешься.
Либо городить огород с CoInitialize/CoCreateInstance в .Net, но чет я не готов к подобным подвигам.
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521553
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Какой еще exception если речь идёт про COM?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521555
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

если только какая-нибудь обёртка ловит код возврата и генерирует исключение. ты про какой случай говоришь?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521581
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttДмитрий77,

Какой еще exception если речь идёт про COM?самый обыкновенный- стандартный маршаллинг HRESULT
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521584
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttДмитрий77,

если только какая-нибудь обёртка ловит код возврата и генерирует исключение. ты про какой случай говоришь?
стандартый маршаллер так действует


рекомендации MS- typelib поправить или сборку импортную покалечить (ilasm-ildasm)
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521586
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521589
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttДмитрий77,

Какой еще exception если речь идёт про COM?
В первом посте код приведен.
.ConnectedSubmit2 дает ошибку, уходим в Catch
Не, можно On Error Resume Next как в VB6, а потом Err.Number/Err.Description, будут те же яйца только в профиль.
Код: vbnet
1.
2.
3.
4.
5.
6.
Try
...
   iErrorIndex = .ConnectedSubmit2(objFaxServer, strJobIds)
Catch ex As Exception
   MsgBox(ex.Message)
End Try


Ты описание проблемы почитай полностью.
Вот тебе этот COM прикреплен.
20788648
(брать надо из папки Vista_Win10)
Ну либо просто добавь ссылку на "Microsoft Fax Service Extended COM Type Library".
Надо получить plErrorBodyFile, я не знаю как это сделать из VB (да и из C# -пофиг).
Ну как бы либо читай первый пост внимательно если есть желание врубиться, помочь, подсказать, высказаться по теме , ну либо не отвечай ничего что ли.
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521612
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилрекомендации MS- typelib поправить или сборку импортную покалечить (ilasm-ildasm)
Изопропил https://msdn.microsoft.com/en-us/library/8zbc969t(v=vs.90).aspx
Я так понимаю, мне сюда копать?
Т.е. я должен по сути переписать Interop (нужную ф-цию) таким образом, чтоб вместо вылета в Exeption,
возвращался HRESULT, который я разбираю типа как при работе с API,
S_OK - хорошо, все остальное плохо,
ну и чтобы ловилось то что мне нужно ByRef (как в оригинале).
Уловил верно?

ilasm-ildasm это утилиты какие-то?
Здесь подвопрос. У меня Interop "универсальный" под .Net 2.0.(чтоб работал под 2.0/3.5/4.5 Debug/Release x64/Win32) Возможно в скобках частично глупости и несущественное.
Ну т.е. если я его туда-сюда курочу, то надо чтоб был "такой же". Как это соотносится с ilasm-ildasm?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521621
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>ilasm-ildasm
А где эти exe-шники лежат?
И от какой студии их брать под .Net 2.0? 2005? 2005 у меня только C++ стоит (полная и Express).
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521622
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Т.е. я должен по сути переписать Interop (нужную ф-цию) таким образом, чтоб вместо вылета в Exeption,
возвращался HRESULT, который я разбираю типа как при работе с API,

Ну ок. Отловить эксепшен и прочитать код ошибки, не?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521626
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
try
{
    // COM call
}
catch(COMException ex)
{
    int error = ex.ErrorCode; // это?

}
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521628
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521631
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Ну как бы либо читай первый пост внимательно если есть желание врубиться, помочь, подсказать, высказаться по теме , ну либо не отвечай ничего что ли.

Да пофиг, возвращается эксепшен, лови его и читай код ошибки.
Не возвращается, получаей код ошибки.

Какие ещё варианты?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521648
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,
с Try Catch все понятно и так (ну не объясняй мне этот .Net-овский детский сад пожалуйста).
мне нужен не код ошибки, а индекс документа, который эту ошибку вызвал
Код: plaintext
1.
2.
3.
4.
5.
HRESULT ConnectedSubmit2(
  [in]           IFaxServer *pFaxServer,
  [out]          VARIANT *pvFaxOutgoingJobIDs,
  [out, retval]  LONG *plErrorBodyFile
);


>возвращается эксепшен, лови его и читай код ошибки.
>Не возвращается, получаей код ошибки.
эксепшен ловит только HRESULT, то чего мне надо он не ловит

Изопропил кажется дело говорит.

Пока нашел
C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin\ildasm.exe (v.2.0.50727.42 -наверно пойдет с учетом сказанного)
Что-то я там ilasm.exe не вижу.
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521651
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttНу ок. Отловить эксепшен и прочитать код ошибки, не?
кроме кода ошибки нужно значение выходного параметра
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521653
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странно,
ilasm.exe
нигде нету, вообще никакого.
Делал поиск в обоих Program Files.
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521656
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

ilasm живёт в C:\Windows\Microsoft.NET\Framework64\...
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521667
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77>возвращается эксепшен, лови его и читай код ошибки.
>Не возвращается, получаей код ошибки.
эксепшен ловит только HRESULT, то чего мне надо он не ловит

Изопропил кажется дело говорит.

Хм.. может тогда лучше в CLI сделать свою обёртку?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521672
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttДмитрий77>возвращается эксепшен, лови его и читай код ошибки.
>Не возвращается, получаей код ошибки.
эксепшен ловит только HRESULT, то чего мне надо он не ловит

Изопропил кажется дело говорит.

Хм.. может тогда лучше в CLI сделать свою обёртку?
исправлением или ручным созданием импорта обычно обходятся
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521675
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилисправлением или ручным созданием импорта обычно обходятся

Ручное создание импорта это что?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521677
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилilasm живёт в C:\Windows\Microsoft.NET\Framework64\...
Тогда наверно вот этот в самый раз:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe (v.2.0.50727.8745)

Ну допустим сделал команду
C:\Setup\Tests\Interop>ildasm Interop.FAXCOMEXLib.dll /out:Interop.FAXCOMEXLib.il
Получился Interop.FAXCOMEXLib.il, по умолчанию ничем не открывается.

Ты мне когда-то присоветовал ILSpy - есть такой на компе.
Ну им в принципе и сам Interop можно открыть.
А им (ILSpy) нельзя просто покурочить и пересохранить? File -> Save Code ? (в смысле без ilasm-ildasm)

А чего и как курочить?
Про IFaxDocument2-> ConnectedSubmit2 там на желтеньком справа написано
Код: c#
1.
2.
3.
4.
// FAXCOMEXLib.IFaxDocument2
[DispId(23)]
[MethodImpl(MethodImplOptions.InternalCall)]
int ConnectedSubmit2([MarshalAs(UnmanagedType.Interface)] [In] IFaxServer pFaxServer, [MarshalAs(UnmanagedType.Struct)] out object pvFaxOutgoingJobIDs);
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521683
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt,

при импорте tlb никакой мистики не происходит - сборка с описанием интеропа создаётся
такую сборку можно и руками сделать(tlb и кривыми бывают)
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521690
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилhVostt,

при импорте tlb никакой мистики не происходит - сборка с описанием интеропа создаётся
такую сборку можно и руками сделать(tlb и кривыми бывают)

Ну так что ты имеешь в виду, руками сделать?
...
Рейтинг: 0 / 0
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
    #39521709
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

ну я понял, il это текстовуха, открыл пока в блокноте
На тему ConnectedSubmit2 есть в двух местах:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
  .method public hidebysig newslot virtual 
          instance int32  ConnectedSubmit2([in] class FAXCOMEXLib.IFaxServer  marshal( interface ) pFaxServer,
                                           [out] object&  marshal( struct) pvFaxOutgoingJobIDs) runtime managed internalcall
  {
    .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 17 00 00 00 00 00 ) 
    .override FAXCOMEXLib.IFaxDocument2::ConnectedSubmit2
  } // end of method FaxDocumentClass::ConnectedSubmit2

  .method public hidebysig newslot abstract virtual 
          instance int32  ConnectedSubmit2([in] class FAXCOMEXLib.IFaxServer  marshal( interface ) pFaxServer,
                                           [out] object&  marshal( struct) pvFaxOutgoingJobIDs) runtime managed internalcall
  {
    .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 17 00 00 00 00 00 ) 
  } // end of method IFaxDocument2::ConnectedSubmit2


и никаких намеков на
Код: plaintext
1.
2.
3.
4.
5.
HRESULT ConnectedSubmit2(
  [in]           IFaxServer *pFaxServer,
  [out]          VARIANT *pvFaxOutgoingJobIDs,
  [out, retval]  LONG *plErrorBodyFile
);


И че мне с этим делать?
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / (COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]