Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / (COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop) / 25 сообщений из 33, страница 1 из 2
14.09.2017, 21:52
    #39521386
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Используем 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
15.09.2017, 09:29
    #39521543
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Не, но это фигня какая-то
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
15.09.2017, 09:49
    #39521553
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Дмитрий77,

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

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

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

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


рекомендации MS- typelib поправить или сборку импортную покалечить (ilasm-ildasm)
...
Рейтинг: 0 / 0
15.09.2017, 10:21
    #39521586
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
...
Рейтинг: 0 / 0
15.09.2017, 10:23
    #39521589
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
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
15.09.2017, 10:51
    #39521612
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Изопропилрекомендации 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
15.09.2017, 10:59
    #39521621
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
>ilasm-ildasm
А где эти exe-шники лежат?
И от какой студии их брать под .Net 2.0? 2005? 2005 у меня только C++ стоит (полная и Express).
...
Рейтинг: 0 / 0
15.09.2017, 11:01
    #39521622
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Дмитрий77Т.е. я должен по сути переписать Interop (нужную ф-цию) таким образом, чтоб вместо вылета в Exeption,
возвращался HRESULT, который я разбираю типа как при работе с API,

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

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

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

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

Какие ещё варианты?
...
Рейтинг: 0 / 0
15.09.2017, 11:21
    #39521648
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
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
15.09.2017, 11:27
    #39521651
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
hVosttНу ок. Отловить эксепшен и прочитать код ошибки, не?
кроме кода ошибки нужно значение выходного параметра
...
Рейтинг: 0 / 0
15.09.2017, 11:28
    #39521653
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Странно,
ilasm.exe
нигде нету, вообще никакого.
Делал поиск в обоих Program Files.
...
Рейтинг: 0 / 0
15.09.2017, 11:30
    #39521656
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Дмитрий77,

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

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

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

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

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

Ручное создание импорта это что?
...
Рейтинг: 0 / 0
15.09.2017, 11:51
    #39521677
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
Изопропил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
15.09.2017, 11:55
    #39521683
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(COM) Разная интерпретация одного и того же метода в С++ и Vb.Net/C#(Interop)
hVostt,

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

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

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

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


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