Marshalling II







Updated on July 29,2025 
  1. #include <iostream>
  2. namespace Chen { int My_Console_Main(const wchar_t* comment); }

  3. int main()
  4. {
  5.     std::cout << "Hello World!\n";
  6.     return Chen::My_Console_Main(L"Startup project with =====> MFC");

  7. }




Updated on July 29,2025 
  1. #include "Windows.h"
  2. #include "shlwapi.h"
  3. #include "Psapi.h"
  4. #include "stdexcept"
  5. #include "stdarg.h"
  6. #include "stdio.h"
  7. #define AfxLoadLibrary  LoadLibraryW
  8. #define AfxFreeLibrary  FreeLibrary   

  9. #if defined(_M_AMD64) && defined(_WIN64) && defined(_CONSOLE) && \
  10.     _MSVC_LANG >= 201703L 
  11. #include "TestParameter.h"
  12. namespace Chen {
  13.     int My_Console_Main(const wchar_t* comment);

  14. #define CreationInstance_clsid  OLESTR("91DD12FD-4DBD-4B83-AC40-439E3B6393A1")
  15. #define CreationInstance_iid    OLESTR("85927839-0BB2-423B-97D6-89A2D4002519")


  16. #ifdef _DEBUG
  17.     const LPCWSTR MyDllname =
  18.         L"MFC_DLL_Test_Marshalling\\x64\\Debug\\MFCDLLTestMarshalling.dll";

  19.     const LPCWSTR MyDllname2 =
  20.         L"CPP_Dll_Test_Marshalling\\x64\\Debug\\CPP_Dll_Test_Marshalling.dll";
  21. #else
  22.     const LPCWSTR MyDllname =
  23.         L"MFC_DLL_Test_Marshalling\\x64\\Release\\MFCDLLTestMarshalling.dll";

  24.     const LPCWSTR MyDllname2 =
  25.         L"CPP_Dll_Test_Marshalling\\x64\\Release\\CPP_Dll_Test_Marshalling.dll";
  26. #endif // DEBUG

  27.     typedef struct {
  28.         LPCWSTR DLL_Path;
  29.         LPCSTR ProcName;
  30.         BOOL   MFC_DLL;
  31.     } ClientInfo_Struct;

  32.     ClientInfo_Struct ClientInfo[]{
  33.        {
  34.            MyDllname,
  35.            "MFC_DLL_Test_UnregisteredServer1",
  36.            true
  37.        },{
  38.            MyDllname,
  39.            "MFC_DLL_Test_UnregisteredServer2",
  40.            true
  41.        },{
  42.            MyDllname,
  43.            "MFC_DLL_Test_IXXXX",
  44.            true
  45.        },{
  46.            MyDllname2,
  47.            "CPP_DLL_Test_UnregisteredServer1",
  48.            false
  49.        },{
  50.            MyDllname2,
  51.            "CPP_DLL_Test_UnregisteredServer2",
  52.            false
  53.        },{
  54.            MyDllname2,
  55.            "CPP_DLL_Test_IXXXX",
  56.            false
  57.        }
  58.     };

  59.     void Get_CreationInstance_To_Create_UnregisteredServer(
  60.         _In_  LPCOLESTR CLSID_String,
  61.         _In_  LPCOLESTR IID_String);
  62.     void My_Test_Function();
  63.     void ReleaseResource();
  64.     void ErrorMessage(const CHAR* ERR_MSG);
  65.     namespace Debug_namespace {
  66.         inline namespace FileForDebug_namespace {
  67.             const size_t BufferSize_File = 5UI64 << 20;
  68.             class FileForDebug {
  69.                 bool OnDebug;
  70.                 bool IsSave;
  71.                 bool TooLarge;
  72.                 WCHAR  previousCHAR[BufferSize_File];
  73.                 WCHAR* pStart_Previous;
  74.                 size_t ReadSize, WriteSize;

  75.             public:
  76.                 FileForDebug();
  77.                 void compareData(const wchar_t* pStart, int size);
  78.                 void Save();
  79.             };
  80.             FileForDebug* MyFileForDebug;
  81.         }

  82.         inline namespace ExportedData_namespace {

  83.             const size_t BufferSize_Line = 1500UI64;
  84.             WCHAR MyLine[BufferSize_Line + 3];
  85.             size_t size;
  86.             va_list My_va_list;
  87.             void OutputFunction(const WCHAR* str, int size) {
  88.                 wprintf(L"%s", str);
  89.                 MyFileForDebug->compareData(str, size);
  90.             }
  91.             void Ellipsis() {
  92.                 size = BufferSize_Line - 1;
  93.                 *(MyLine + size++) = L'.';
  94.                 *(MyLine + size++) = L'.';
  95.                 *(MyLine + size++) = L'.';
  96.                 *(MyLine + size) = L'\0';
  97.                 OutputFunction(MyLine, (int)size);
  98.                 // printf("size= %I64u   BufferSize_Line=%I64u\n", 
  99.                 //  size, BufferSize_Line);system("pause");
  100.             }
  101.             void AppendNewline() {
  102.                 *(MyLine + size++) = L'\r';
  103.                 *(MyLine + size++) = L'\n';
  104.                 *(MyLine + size) = L'\0';
  105.                 OutputFunction(MyLine, (int)size);
  106.             }
  107.             void My_Write_Line(const WCHAR* format, va_list va_list) {
  108.                 size = _vsnwprintf_s(MyLine, BufferSize_Line, _TRUNCATE, format, va_list);
  109.                 if (size >= BufferSize_Line) Ellipsis();
  110.                 else AppendNewline();
  111.             }
  112.             void  MyWriteLine(const WCHAR* format, ...) {
  113.                 va_start(My_va_list, format);
  114.                 My_Write_Line(format, My_va_list);
  115.                 va_end(My_va_list);
  116.             }
  117.             void My_Write(const WCHAR* format, va_list va_list) {
  118.                 size = _vsnwprintf_s(MyLine, BufferSize_Line, _TRUNCATE, format, va_list);
  119.                 if (size >= BufferSize_Line) Ellipsis();
  120.                 else  OutputFunction(MyLine, (int)size);
  121.             }
  122.             void  MyWrite(const WCHAR* format, ...) {
  123.                 va_start(My_va_list, format);
  124.                 My_Write(format, My_va_list);
  125.                 va_end(My_va_list);
  126.             }
  127.         }
  128.     }
  129.     using Debug_namespace::MyWriteLine;
  130.     using Debug_namespace::MyFileForDebug;
  131.     using Debug_namespace::FileForDebug;

  132.     class MyException : public std::exception {
  133.         const char* ExceptionString;
  134.     public:
  135.         int errorNo;
  136.         MyException(const char* Exception_MSG, int errorNo) :
  137.             ExceptionString(Exception_MSG), errorNo(errorNo) {
  138.         }
  139.         virtual const char* what()const;
  140.     };
  141.     const char* MyException::what()const { return ExceptionString; }
  142. #define NTFS_MAX_PATH ( 32llu <<10)
  143.     WCHAR Current_Directory[NTFS_MAX_PATH];
  144.     WCHAR ProcessImageFileName[NTFS_MAX_PATH];
  145.     WCHAR ModuleFileName[NTFS_MAX_PATH];
  146.     WCHAR APP_Dir[NTFS_MAX_PATH];
  147.     WCHAR MyPathRoot[NTFS_MAX_PATH];
  148.     HANDLE hThread;
  149.     DWORD ProcessID;
  150.     HANDLE hProcess;
  151.     HRESULT hr;
  152.     IUnknown* pIUnknown;
  153.     ICreationInstance* pICreationInstance;
  154.     const bool b_FreeLibrary = false;   //true;
  155.     const size_t hModuleSize = 1000;
  156.     HMODULE hModule_Chen[hModuleSize + (b_FreeLibrary ? 0 : ARRAYSIZE(ClientInfo))];
  157.     HMODULE* phModule_Chen;

  158.     WCHAR ModuleName[NTFS_MAX_PATH];
  159.     void MyEnumModules() {
  160.         if (hProcess) {
  161.             DWORD cbNeeded = 0;
  162.             if (!K32EnumProcessModules(hProcess, phModule_Chen,
  163.                 hModuleSize * sizeof(HMODULE), &cbNeeded)) {
  164.                 ErrorMessage("error: K32EnumProcessModules ");
  165.             }
  166.             for (int i = 0; i < hModuleSize && hModule_Chen[i]; i++) {
  167.                 GetModuleFileNameExW(hProcess, hModule_Chen[i],
  168.                     ModuleName, NTFS_MAX_PATH);
  169.                 printf("%2i %p %S\n", i, hModule_Chen[i], ModuleName);
  170.             }
  171.             int aa = 0;
  172.             for (HMODULE* pLoadedDLL = hModule_Chen; pLoadedDLL < phModule_Chen; pLoadedDLL++) {
  173.                 BOOL FreeLib_OK = (ClientInfo[aa].MFC_DLL ?
  174.                     AfxFreeLibrary : FreeLibrary)(*pLoadedDLL);
  175.                 LPCWSTR DLL_Name = ClientInfo[aa].DLL_Path;
  176.                 if (FreeLib_OK)
  177.                     MyWriteLine(L"  FreeLibrary OK %s\n", DLL_Name);
  178.                 else
  179.                     MyWriteLine(L" error: FreeLibrary %s\n", DLL_Name);
  180.                 aa++;
  181.             }
  182.             phModule_Chen = hModule_Chen;

  183.             printf("hModuleCount=%I64i\n", cbNeeded / sizeof(HMODULE));
  184.             if (K32EnumProcessModules(hProcess, NULL, 0, &cbNeeded))
  185.                 printf("hModuleCount=%I64i\n", cbNeeded / sizeof(HMODULE));
  186.         }
  187.     }
  188.     void AppInitialize() {
  189. #define MyFMT "\t%S\n"
  190.         GetCurrentDirectoryW(NTFS_MAX_PATH, Current_Directory);
  191.         printf("CurrentDir =" MyFMT, Current_Directory);
  192.         phModule_Chen = hModule_Chen;
  193.         hThread = GetCurrentThread();
  194.         ProcessID = GetProcessIdOfThread(hThread);
  195.         hProcess = OpenProcess(
  196.             PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, ProcessID);
  197.         DWORD size = NTFS_MAX_PATH;
  198.         if (!QueryFullProcessImageNameW(hProcess, 0, ProcessImageFileName, &size))
  199.             throw MyException("QueryFullProcessImageNameW", -1004);
  200.         printf("APPFullName=" MyFMT, ProcessImageFileName);
  201.         if (GetModuleFileNameW(NULL, ModuleFileName, NTFS_MAX_PATH) >= NTFS_MAX_PATH)
  202.             throw MyException("GetModuleFileNameW", -1001);
  203.         printf("ModuleFileName=" MyFMT, ModuleFileName);
  204.         wcscpy_s(APP_Dir, NTFS_MAX_PATH, ProcessImageFileName);
  205.         PathCchRemoveFileSpec(APP_Dir, NTFS_MAX_PATH);
  206.         printf("APP_Dir=    " MyFMT, APP_Dir);

  207.         hr = PathCchCombine(MyPathRoot, NTFS_MAX_PATH, APP_Dir, L"..\\..\\..\\");
  208.         if (FAILED(hr))throw MyException("PathCchCombine", -1002);
  209.         PathCchAddBackslash(MyPathRoot, NTFS_MAX_PATH);
  210.         printf("MyPathRoot=" MyFMT, MyPathRoot);

  211.         // ---> For debug 
  212.         printf("RelativePath=\t%100S\n", MyDllname);
  213.         const WCHAR* pFullPath = ToFullPath(MyPathRoot, MyDllname);
  214.         if (PathFileExistsW(pFullPath))
  215.             printf("    FullPath= \t%100S\n", pFullPath);
  216.         else  printf("file not exist\t%100S\n", MyDllname);
  217.         // ---> For debug 
  218.         system("pause");
  219.     }
  220.     int My_Console_Main(const wchar_t* comment) {
  221.         printf("%S\n", comment);
  222.         printf("CommandLine=%s\n", GetCommandLineA());
  223.         AppInitialize();
  224.         try {
  225.             MyFileForDebug = new FileForDebug();
  226.             hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
  227.             if (FAILED(hr))throw MyException("CoInitializeEx", -1);
  228.             hr = OleInitialize(NULL);
  229.             if (FAILED(hr))throw MyException("OleInitialize", -2);

  230.             Get_CreationInstance_To_Create_UnregisteredServer(
  231.                 CreationInstance_clsid, CreationInstance_iid);
  232.             for (int ff = 0; ff < 3; ff++) {
  233.                 My_Test_Function();
  234.                 MyEnumModules();
  235.                 system("pause");
  236.             }
  237.             OleUninitialize();
  238.             CoUninitialize();
  239.             MyFileForDebug->Save();
  240.             ReleaseResource();
  241.             system("pause");
  242.         }
  243.         catch (const MyException& ex) {
  244.             printf("errorNo=%d\n", ex.errorNo);
  245.             ErrorMessage(ex.what());
  246.             return ex.errorNo;
  247.         }
  248.         catch (const std::exception& ex) {
  249.             ErrorMessage(ex.what());
  250.             return -1000;
  251.         }
  252.         return 0;
  253.     }
  254.     void Get_CreationInstance_To_Create_UnregisteredServer(
  255.         _In_ LPCOLESTR CLSID_String, _In_ LPCOLESTR IID_String) {
  256.         CLSID MyClsid;
  257.         hr = CLSIDFromString(AddCurlyBracket(CLSID_String), &MyClsid);
  258.         if (FAILED(hr))throw MyException("CLSIDFromString", -11);
  259.         hr = CoCreateInstance(MyClsid, NULL, CLSCTX_INPROC_SERVER,
  260.             IID_IUnknown, (LPVOID*)&pIUnknown);
  261.         if (FAILED(hr))throw MyException("CoCreateInstance", -12);
  262.         IID MyIID;
  263.         hr = IIDFromString(AddCurlyBracket(IID_String), &MyIID);
  264.         if (FAILED(hr))throw MyException("IIDFromString", -13);
  265.         hr = pIUnknown->QueryInterface(MyIID, (void**)&pICreationInstance);
  266.         if (FAILED(hr))throw MyException("QueryInterface", -14);

  267.         if (pIUnknown + 1 != pICreationInstance) {
  268.             ErrorMessage("pIUnknown + 1 ");
  269.         }
  270.         BSTR Description = ::SysAllocStringByteLen("", 5000);
  271.         if (!Description)throw MyException("SysAllocStringLen", -15);
  272.         hr = pICreationInstance->GetDescription(Description);
  273.         if (FAILED(hr)) {
  274.             ::SysFreeString(Description);
  275.             throw MyException("GetDescription", -16);
  276.         }
  277.         // printf("%d", (*(INT32*)Description));
  278.         MyWriteLine(L"%s", Description + 2);
  279.         ::SysFreeString(Description);
  280.         hr = pICreationInstance->GetDescription2(&Description);
  281.         if (FAILED(hr)) throw MyException("GetDescription2", -17);
  282.         MyWriteLine(L"%s", Description);
  283.         ::SysFreeString(Description);
  284.     }

  285.     void My_Test_Function() {
  286.         int length = ARRAYSIZE(ClientInfo);
  287.         for (int aa = 0; aa < length; aa++) {
  288.             HMODULE& hModule = *phModule_Chen++;
  289.             const WCHAR* DLL_Absolute_Path = ToFullPath(MyPathRoot, ClientInfo[aa].DLL_Path);
  290.             hModule = ClientInfo[aa].MFC_DLL ?
  291.                 AfxLoadLibrary(DLL_Absolute_Path) : LoadLibraryW(DLL_Absolute_Path);
  292.             if (!hModule)throw MyException("LoadLibraryW", -21);
  293.             using Test_UnregisteredServer = int (*)(TestParameter*);
  294.             Test_UnregisteredServer FunctionPointer =
  295.                 (Test_UnregisteredServer)GetProcAddress(hModule, ClientInfo[aa].ProcName);
  296.             if (!FunctionPointer) {
  297.                 if (b_FreeLibrary) {
  298.                     ClientInfo[aa].MFC_DLL ?
  299.                         AfxFreeLibrary(hModule) : FreeLibrary(hModule);
  300.                     --phModule_Chen;
  301.                 }
  302.                 throw MyException("GetProcAddress", -22);
  303.             }
  304.             TestParameter MyParameter = {
  305.                  Debug_namespace::My_Write_Line,
  306.                  pICreationInstance ,
  307.                  MyPathRoot
  308.             };
  309.             int rv = FunctionPointer(&MyParameter);
  310.             if (b_FreeLibrary) {
  311.                 ClientInfo[aa].MFC_DLL ?
  312.                     AfxFreeLibrary(hModule) : FreeLibrary(hModule);
  313.                 --phModule_Chen;
  314.             }
  315.             if (rv < 0)throw MyException("Test unregistered server Function", rv);
  316.         }
  317.     }

  318.     void ReleaseResource() {

  319.         IDispatch* pIDispatch;
  320.         hr = pIUnknown->QueryInterface(IID_IDispatch, (void**)&pIDispatch);
  321.         if (FAILED(hr))
  322.             ErrorMessage("QueryInterface (IID_IDispatch ");
  323.         else
  324.             printf("   %p(%d)pIDispatch\n", pIDispatch, pIDispatch->Release());
  325.         printf("   %p(%d)pIUnknown\n", pIUnknown, pIUnknown->Release());
  326.         printf("   %p(%d)pICreationInstance\n", pICreationInstance,
  327.             pICreationInstance->Release());
  328.     }
  329.     void ErrorMessage(const CHAR* ERR_MSG) {
  330.         MessageBeep(MB_ICONERROR);
  331.         HANDLE herr = GetStdHandle(STD_ERROR_HANDLE);
  332.         CONSOLE_SCREEN_BUFFER_INFO Screen_Buf;
  333.         GetConsoleScreenBufferInfo(herr, &Screen_Buf);
  334.         SetConsoleTextAttribute(herr, FOREGROUND_RED);
  335.         fprintf(stderr, "%s\n", ERR_MSG);

  336.         SetConsoleTextAttribute(herr, FOREGROUND_GREEN);
  337.         int NoOpenStream = _flushall();//printf("No=%d\n", NoOpenStream);
  338.         system("pause");
  339.         SetConsoleTextAttribute(herr, Screen_Buf.wAttributes);
  340.     }

  341. #define MyDebugFilename "MyFileForDebug.txt"
  342. #define _WMyDebugFilename OLESTR("MyFileForDebug.txt")
  343.     Debug_namespace::FileForDebug::FileForDebug() :
  344.         IsSave(false),
  345.         OnDebug(false),
  346.         TooLarge(false),
  347.         previousCHAR{}, WriteSize(0), ReadSize(0),
  348.         pStart_Previous(previousCHAR)
  349.     {
  350.         FILE* _Stream = NULL;
  351.         errno_t errNo = _wfopen_s(&_Stream, ToFullPath(APP_Dir, _WMyDebugFilename), L"r,ccs=UNICODE");
  352.         if (!_Stream || errNo) {
  353.             ErrorMessage("Unable to open " MyDebugFilename);
  354.             return;
  355.         }
  356.         ReadSize = fread_s(previousCHAR, sizeof(previousCHAR),
  357.             sizeof(previousCHAR[0]), BufferSize_File, _Stream);
  358.         fclose(_Stream);
  359.         OnDebug = true;
  360.         printf("BufferSize_File=%lluMB ReadFileSize=%llu\n", (BufferSize_File >> 20), ReadSize);
  361.         system("pause");
  362.     }
  363.     void Debug_namespace::FileForDebug::Save() {
  364.         if (IsSave || OnDebug) return;
  365.         FILE* _Stream = NULL;
  366.         errno_t errNo = _wfopen_s(&_Stream, ToFullPath(APP_Dir, _WMyDebugFilename), L"w,ccs=UNICODE");
  367.         if (_Stream && !errNo) {
  368.             WriteSize = fwrite(previousCHAR, sizeof(previousCHAR[0]),
  369.                 pStart_Previous - previousCHAR, _Stream);
  370.             fclose(_Stream);
  371.             IsSave = true;
  372.             printf("BufferSize_File=%I64u  ReadFileSize= %I64u\n", BufferSize_File, ReadSize);
  373.             printf("BufferSize_File=%I64u  WriteFileSize=%I64u\n", BufferSize_File, WriteSize);
  374.             system("pause");
  375.         }
  376.     }
  377.     void  Debug_namespace::FileForDebug::compareData(const wchar_t* pStart, int size) {
  378.         if (TooLarge)return;
  379.         if (pStart_Previous + size > previousCHAR + BufferSize_File) {
  380.             TooLarge = true;
  381.             ErrorMessage("Output data Too Large in compareData");
  382.             return;
  383.         }
  384.         if (OnDebug) {
  385.             int ret = memcmp(pStart, pStart_Previous, sizeof(wchar_t) * size);
  386.             if (ret) {
  387.                 OnDebug = false;
  388.                 ErrorMessage("The output is not consistent with previous one");
  389.             }
  390.             else { pStart_Previous += size; return; }
  391.         }
  392.         if (memcpy_s(pStart_Previous, size * sizeof(wchar_t),
  393.             pStart, size * sizeof(wchar_t))) {
  394.             ErrorMessage("memcpy_s");
  395.         }
  396.         pStart_Previous += size;
  397.     }

  398. };
  399. #endif 














  1. #pragma once
  2. #include "PathCch.h"
  3. __interface ICreationInstance :IDispatch
  4. {
  5.     HRESULT Get_Interface3(
  6.         _In_ PVOID AssemblyInfo_ptr,
  7.         _COM_Outptr_ PVOID* ppvid);
  8.     HRESULT GetDescription(
  9.         _In_ BSTR description);
  10.     HRESULT GetDescription2(
  11.         _Out_ BSTR* description);
  12. };

  13. typedef void (*MyWriteLine)(const WCHAR* format, va_list);

  14. struct TestParameter {
  15.     MyWriteLine MyWriteLine;
  16.     PVOID ptr_to_Interface;
  17.     const WCHAR* PathRoot;
  18. };
  19. const WCHAR* AddCurlyBracket(const WCHAR* uuid) {
  20.     const size_t MAX_index = 5, Max_length = 40;
  21.     static WCHAR TempUUID[MAX_index][Max_length + 3];
  22.     static size_t index = 0;
  23.     if (++index >= MAX_index)index = 0;
  24.     WCHAR* const UUID_ = TempUUID[index];
  25.     size_t size_uuid = wcsnlen_s(uuid, Max_length);
  26.     wcsncpy_s(UUID_ + 1, Max_length, uuid, size_uuid);
  27.     UUID_[0] = L'{';                   // '\u007b';
  28.     UUID_[size_uuid + 1] = L'}';      //'\u007d';
  29.     UUID_[size_uuid + 2] = L'\u0000';  // '\0';
  30.     //wprintf(L"%s\n", UUID_);system("pause");
  31.     return TempUUID[index];
  32. }
  33. const WCHAR* ToFullPath(const WCHAR* pRoot, const WCHAR* relativePath) {
  34.     const size_t MAX_index = 5, Max_length = 4000;
  35.     static WCHAR tempFullPath[MAX_index][Max_length];
  36.     static size_t index = 0;
  37.     if (++index >= MAX_index)index = 0;
  38.     wcscpy_s<Max_length>(tempFullPath[index], pRoot);
  39.     PathCchAppend(tempFullPath[index], Max_length, relativePath);
  40.     return tempFullPath[index];
  41. }
  42. class ExportedData {
  43.     MyWriteLine MyWriteLine;
  44.     const WCHAR* start;
  45.     va_list My_va_list;
  46.     static inline ExportedData* ED_ptr = nullptr;
  47. public:
  48.     static inline ExportedData* const MySelf() { return ED_ptr; }
  49.     void WriteLine(const WCHAR* format, ...) {
  50.         va_start(My_va_list, format);
  51.         MyWriteLine(format, My_va_list);
  52.         va_end(My_va_list);
  53.     }
  54.     ExportedData(TestParameter* pTestParameter, const WCHAR* start) {
  55.         MyWriteLine = pTestParameter->MyWriteLine;
  56.         this->start = start;
  57.         ED_ptr = this;
  58.         WriteLine(L"====== Begin %s =======", start);
  59.     }
  60.     ~ExportedData() {
  61.         WriteLine(L"====== End %s   =======", start);
  62.         ED_ptr = nullptr;
  63.         //system("pause");
  64.     }
  65. };











                                                

    
                                       









  1. #If TARGET = "library" And PLATFORM = "x64" Then
  2. Option Strict On
  3. Imports System.Reflection
  4. Imports System.Runtime.InteropServices
  5. Imports System.Text
  6. <ComClass(
  7.     "91DD12FD-4DBD-4B83-AC40-439E3B6393A1",
  8.     "85927839-0BB2-423B-97D6-89A2D4002519"
  9.     )>
  10. Public Class RegisteredLib
  11.     Sub Get_Interface3(<[In]> AssemblyInfo_ptr As IntPtr,
  12.                        <Out> ByRef ppVoid As IntPtr)
  13.         Try
  14.             MyAssemblyInfo =
  15.               Marshal.PtrToStructure(Of AssemblyInfo_Struct)(AssemblyInfo_ptr)
  16.             AssemblyPath =
  17.               Marshal.PtrToStringBSTR(MyAssemblyInfo.AssemblyPath)
  18.             UnregisteredServerAssembly = Assembly.LoadFrom(AssemblyPath)
  19.             InvokeCreationMethod()
  20.             ppVoid = Marshal.ReadIntPtr(ppvoid_temp)
  21.         Catch ex As IO.FileNotFoundException
  22.             MsgBox("Not found " & AssemblyPath & "--Chen")
  23.             Throw New MyException(&HE0000001, "FileNotFoundException")
  24.         Catch ex As Exception
  25.             Throw New MyException(&HE0000111,
  26.                    $"Unknown Exception--{ex.Message}")
  27.         End Try
  28.     End Sub
  29.     Sub GetDescription(Description As IntPtr)
  30.         Dim Source As New StringBuilder(
  31.          "This is a CreationInstance for getting unregistered servers")
  32.         Source.AppendLine()
  33.         Source.AppendLine("HRESULT value reference : winerror.h")
  34.         Source.AppendLine(
  35.            "My location is " &
  36.                System.Reflection.Assembly.GetExecutingAssembly.Location)
  37.         Source.AppendLine(
  38.            "FrameworkDescription is " &
  39.         System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription
  40.         )

  41.         Dim MainType As Type = GetType(RegisteredLib)
  42.         Dim ThisModule As Reflection.Module = MainType.Module
  43.         Dim peKind As PortableExecutableKinds
  44.         Dim machine As ImageFileMachine
  45.         ThisModule.GetPEKind(peKind, machine)
  46.         Source.AppendFormat("machine={0:G} peKind={1:G}", machine, peKind)
  47.         Source.Append(ChrW(0))
  48.         Dim BufferSize As Int32 = Marshal.ReadInt32(Description - 4)
  49.         If BufferSize < (4 + Source.Length * 2) Then
  50.             Marshal.WriteInt32(Description, 0)
  51.         End If
  52.         Marshal.Copy(Source.ToString().ToCharArray(), 0,
  53.                      Description + 4, Source.Length)
  54.         Marshal.WriteInt32(Description, (Source.Length - 1) * 2)
  55.     End Sub
  56.     Sub GetDescription2(<Out> ByRef Description As String)
  57.         Dim MainType As Type = GetType(RegisteredLib)
  58.         Dim ThisModule As Reflection.Module = MainType.Module
  59.         Dim peKind As PortableExecutableKinds
  60.         Dim machine As ImageFileMachine
  61.         ThisModule.GetPEKind(peKind, machine)
  62.         Dim Source As New StringBuilder(
  63.          "This is a CreationInstance for getting unregistered servers" &
  64.     vbNewLine & "HRESULT value reference : winerror.h" &
  65.     vbNewLine & "My location is " &
  66.      System.Reflection.Assembly.GetExecutingAssembly.Location &
  67.     vbNewLine & "FrameworkDescription is " &
  68.      System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription &
  69.     vbNewLine & $"machine={machine} peKind={peKind}"
  70.     )
  71.         Description = Source.ToString()
  72.     End Sub

  73.     '============================================================
  74.     Public Sub New()
  75.         MyBase.New()
  76.         ppvoid_temp = Marshal.AllocCoTaskMem(12)
  77.     End Sub
  78.     Protected Sub Finallize()
  79.         Marshal.FreeCoTaskMem(ppvoid_temp)
  80.     End Sub
  81.     Private Class MyException
  82.         Inherits Exception
  83.         Sub New(errorcode As Int32, Message As String)
  84.             MyBase.New(Message)
  85.             HResult = errorcode
  86.         End Sub
  87.     End Class
  88.     Dim MyAssemblyInfo As AssemblyInfo_Struct
  89.     Structure AssemblyInfo_Struct
  90.         Public AssemblyPath As IntPtr
  91.         Public TypeFullname As IntPtr
  92.         Public CreationMethod As IntPtr
  93.         Public CLSID As IntPtr
  94.         Public IID As IntPtr
  95.     End Structure
  96.     Dim AssemblyPath As String
  97.     Dim TypeFullname As String
  98.     Dim CreationMethod As String
  99.     Dim CLSID_string As String
  100.     Dim IID_string As String
  101.     ReadOnly ppvoid_temp As IntPtr
  102.     Dim UnregisteredServerAssembly As Assembly
  103.     Dim IEnumateType As IEnumerable(Of Type)
  104.     Private Sub InvokeCreationMethod()
  105.         Dim Type_CLSID As Guid
  106.         CLSID_string =
  107.          Marshal.PtrToStringBSTR(MyAssemblyInfo.CLSID)
  108.         If Not Guid.TryParse(CLSID_string, Type_CLSID) Then
  109.             Throw New Exception($"Error:CLSID({CLSID_string})")
  110.         End If
  111.         IEnumateType = UnregisteredServerAssembly.ExportedTypes
  112.         For Each MyType As TypeInfo In IEnumateType
  113.             If Type_CLSID <> MyType.GUID Then Continue For
  114.             TypeFullname = Marshal.PtrToStringBSTR(
  115.                 MyAssemblyInfo.TypeFullname)
  116.             If TypeFullname <> MyType.FullName Then
  117.                 MsgBox(TypeFullname & vbNewLine &
  118.                           MyType.FullName)
  119.             End If
  120.             Dim UnregisteredServerType As Type = MyType.AsType
  121.             CreationMethod =
  122.                 Marshal.PtrToStringBSTR(MyAssemblyInfo.CreationMethod)
  123.             Dim CreateObject_Chen As MethodInfo =
  124.                   UnregisteredServerType.GetMethod(CreationMethod)
  125.             If CreateObject_Chen Is Nothing Then
  126.                 Throw New Exception($"Error:CreateMethod({CreationMethod})")
  127.             End If
  128.             IID_string = Marshal.PtrToStringBSTR(MyAssemblyInfo.IID)
  129.             Dim Interface_IID As Guid
  130.             If Not Guid.TryParse(IID_string, Interface_IID) Then
  131.                 Throw New Exception($"Error:Interface_IID({IID_string})")
  132.             End If
  133.             Dim obj() As Object = {Interface_IID, ppvoid_temp, New IntPtr(12345)}
  134.             CreateObject_Chen.Invoke(Nothing, obj)
  135.             Exit Sub
  136.         Next
  137.         Throw New Exception("Error:Nothing")
  138.     End Sub
  139. End Class
  140. #End If





























  1. // MFC_DLL_Test_Marshalling.cpp : Defines the exported functions for the DLL.
  2. //

  3. #include "framework.h"
  4. #include "MFC_DLL_Test_Marshalling.h"
  5. #include <stdio.h>
  6. #include <Combaseapi.h>
  7. #include "oleauto.h"
  8. #include "propvarutil.h"
  9. #include <typeinfo>
  10. #include <type_traits>
  11. #include <concepts>
  12. #include "TestParameter.h"    

  13. // This is an example of an exported variable
  14. MFCDLLTESTMARSHALLING_API int nMFCDLLTestMarshalling=0;

  15. // This is an example of an exported function.
  16. MFCDLLTESTMARSHALLING_API int fnMFCDLLTestMarshalling(void)
  17. {
  18.     return 0;
  19. }

  20. // This is the constructor of a class that has been exported.
  21. CMFCDLLTestMarshalling::CMFCDLLTestMarshalling()
  22. {
  23.     return;
  24. }

  25. #if defined(_M_AMD64) && defined(_WIN64) && defined(_WINDOWS) && \
  26.     defined(_USRDLL) && _MSVC_LANG >= 202002L  

  27. extern "C" /* exported functions */ {
  28.     int MFC_DLL_Test_UnregisteredServer1(TestParameter*);
  29.     int MFC_DLL_Test_UnregisteredServer2(TestParameter*);
  30.     int MFC_DLL_Test_IXXXX(TestParameter*);
  31. }

  32. IUnknown* pIUnknown;
  33. HRESULT hr;

  34. template <class T> concept  Is_BSTR_v = std::is_convertible_v<T, BSTR>;

  35. template <class T> concept  Is_LPCOLESTR_v = std::is_convertible_v<LPCOLESTR, T>;

  36. template <typename T>
  37. struct ServerInfo_Struct {
  38.     T AssemblyPath;
  39.     T TypeFullName;
  40.     T CreationMethod;
  41.     T CLSID;
  42.     T IID;
  43.     ServerInfo_Struct(T t1, T t2, T t3, T t4, T t5) :
  44.         AssemblyPath(t1),
  45.         TypeFullName(t2),
  46.         CreationMethod(t3),
  47.         CLSID(t4),
  48.         IID(t5) {
  49.     }
  50.     ServerInfo_Struct& operator=(ServerInfo_Struct&) = delete;
  51.     ServerInfo_Struct(const ServerInfo_Struct&) = delete;

  52.     ~ServerInfo_Struct() requires Is_BSTR_v<T> {
  53.         if (0 == strcmp(typeid(T).name(), typeid(BSTR).name())) {
  54.             printf("std::is_convertible_v< %s , %s >\n",
  55.                 typeid(T).name(), typeid(BSTR).name());
  56.         }
  57.         else printf("===> Error:%s\n", typeid(T).name());

  58.         ::SysFreeString((wchar_t*)AssemblyPath);
  59.         ::SysFreeString((wchar_t*)TypeFullName);
  60.         ::SysFreeString((wchar_t*)CreationMethod);
  61.         ::SysFreeString((wchar_t*)CLSID);
  62.         ::SysFreeString((wchar_t*)IID);
  63.     }

  64.     ~ServerInfo_Struct()requires Is_LPCOLESTR_v<T> {
  65.         puts(typeid(T).name());
  66.         if (0 == strcmp(typeid(LPCOLESTR).name(), typeid(T).name())) {
  67.             printf("std::is_convertible_v< %s , %s >\n",
  68.                 typeid(LPCOLESTR).name(), typeid(T).name());
  69.         }
  70.         else printf("===> Error:%s\n", typeid(T).name());
  71.     }

  72. };
  73. template ServerInfo_Struct<LPCOLESTR>;
  74. template ServerInfo_Struct<BSTR>;
  75. #ifdef _DEBUG
  76. const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
  77.     "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Debug\\NotRegisteredServer.dll"
  78. );
  79. #else
  80. const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
  81.     "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Release\\NotRegisteredServer.dll"
  82. );
  83. #endif

  84. ServerInfo_Struct<LPCOLESTR> My_Server_string[] = {
  85.   {
  86.      MyServerName,
  87.      (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer1"),
  88.      (LPCOLESTR)OLESTR("CreateObject3_Chen"),
  89.      (LPCOLESTR)OLESTR("04D9F530-CE0C-4232-8F3F-6E0A3244C715"),
  90.      (LPCOLESTR)OLESTR("31D53FF8-4768-4A77-95E3-DC28DEBB375F")
  91.   },{
  92.      MyServerName,
  93.      (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
  94.      (LPCOLESTR)OLESTR("CreateObject3_Chen"),
  95.      (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
  96.      (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
  97.   },{
  98.      MyServerName,
  99.      (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
  100.      (LPCOLESTR)OLESTR("CreateObject3_Chen"),
  101.      (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
  102.      (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
  103.   }
  104. };
  105. int Get_ServerInterface(TestParameter* ptr, int interfaceID, PVOID* pRetVal) {
  106.     ICreationInstance* pICreationInstance =
  107.         (ICreationInstance*)ptr->ptr_to_Interface;
  108.     ServerInfo_Struct<LPCOLESTR>& MyServerString = My_Server_string[interfaceID];
  109.     ServerInfo_Struct<BSTR> My_Server{
  110.         SysAllocString(ToFullPath(ptr->PathRoot,MyServerString.AssemblyPath)),
  111.         SysAllocString(MyServerString.TypeFullName),
  112.         SysAllocString(MyServerString.CreationMethod),
  113.         SysAllocString(MyServerString.CLSID),
  114.         SysAllocString(MyServerString.IID)
  115.     };
  116.     hr = pICreationInstance->Get_Interface3(&My_Server, (PVOID*)&pIUnknown);
  117.     if (FAILED(hr))return -31;
  118.     IID myiid;
  119.     hr = IIDFromString(AddCurlyBracket(My_Server.IID), &myiid);
  120.     if (FAILED(hr))return -32;
  121.     hr = pIUnknown->QueryInterface(myiid, pRetVal);
  122.     if (FAILED(hr))return -33;
  123.     return 0;
  124. }
  125. /* Begin MFC_DLL_Test_UnregisteredServer1 */
  126. void This_Delegate_will_be_called_While_RaiseEvent(VARIANTARG VAR) {
  127.     ExportedData::MySelf()->WriteLine(L"This_Delegate_will_be_called_While_RaiseEvent(VT_BSTR=%d V_VT(&VAR)=%d)",
  128.         VT_BSTR, V_VT(&VAR));
  129.     ExportedData::MySelf()->WriteLine(L"<-- %s -->", V_BSTR(&VAR));
  130. }
  131. __interface IUnregisteredServer1 :IDispatch
  132. {
  133.     HRESULT Get_Interface(PVOID*);
  134.     HRESULT Get_Interface2(long, VARIANTARG*);
  135.     HRESULT Register_Event(void (*)(VARIANT), BSTR, INT32* ID);
  136.     HRESULT RemoveEvent(INT32 ID);
  137.     HRESULT Raise_Event(LONG64);
  138.     HRESULT Get_MyProperty(INT32*);
  139.     HRESULT Put_MyProperty(INT32 pRetVal);
  140.     HRESULT GetTraceMessage(BSTR*);
  141. };
  142. int MFC_DLL_Test_UnregisteredServer1(TestParameter* ptr) {
  143.     ExportedData ED(ptr, L"MFC_DLL_Test_UnregisteredServer1");
  144.     IUnregisteredServer1* pIUnregisteredServer1;
  145.     int rv = Get_ServerInterface(ptr, 0, (PVOID*)&pIUnregisteredServer1);
  146.     if (rv < 0)return rv;

  147.     INT32 _INT32 = 777;
  148.     ED.WriteLine(L"(%d)", _INT32);
  149.     pIUnregisteredServer1->Get_MyProperty(&_INT32);
  150.     ED.WriteLine(L"(%d)", _INT32);

  151.     INT32 EventID[3]{};
  152.     BSTR MyString_BSTR = SysAllocString(L"Register_Event(&This_Delegate_will_be_called_While_RaiseEvent, MyString_BSTR)");
  153.     for (INT64 aa = 21; aa < 25; aa++) {
  154.         for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
  155.             pIUnregisteredServer1->Register_Event(&This_Delegate_will_be_called_While_RaiseEvent,
  156.                 MyString_BSTR, &EventID[bb]);
  157.         }
  158.         pIUnregisteredServer1->Raise_Event(aa);
  159.         for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
  160.             pIUnregisteredServer1->RemoveEvent(EventID[bb]);
  161.         }
  162.     }
  163.     ::SysFreeString(MyString_BSTR);

  164.     IUnknown* _ptr2_;
  165.     pIUnregisteredServer1->Get_Interface((PVOID*)&_ptr2_);
  166.     if (pIUnknown != _ptr2_) {
  167.         ED.WriteLine(L"Error1:%p", pIUnknown);
  168.         ED.WriteLine(L"Error1:%p", _ptr2_);
  169.     }
  170.     VARIANT _variant;
  171.     VariantInit(&_variant);
  172.     pIUnregisteredServer1->Get_Interface2(2, &_variant);
  173.     if (V_VT(&_variant) != VT_UNKNOWN) {
  174.         ED.WriteLine(L"error: V_VT(&_variant)=%d", V_VT(&_variant));
  175.     }
  176.     _ptr2_ = V_DISPATCH(&_variant);
  177.     if (pIUnknown != _ptr2_) {
  178.         ED.WriteLine(L"Error2:%p", pIUnknown);
  179.         ED.WriteLine(L"Error2:%p", _ptr2_);
  180.     }

  181.     BSTR MyMessage = NULL;
  182.     pIUnregisteredServer1->GetTraceMessage(&MyMessage);
  183.     ED.WriteLine(L"GetTraceMessage");
  184.     ED.WriteLine(L"%s", MyMessage);
  185.     SysFreeString(MyMessage);
  186.     return 0;
  187. }
  188. /* End  MFC_DLL_Test_UnregisteredServer1 */
  189. // 1 ======================================================= 2
  190. /* Begin MFC_DLL_Test_UnregisteredServer2 */
  191. __interface IUnregisteredServer2_CPP :public IDispatch
  192. {
  193. public:
  194.     HRESULT DefaultMarshallingForObject(VARIANT* v, VARIANT* v2, VARIANT* v3);
  195.     HRESULT Map_HResultAndException(BSTR* display);
  196.     HRESULT Hello_world3(
  197.         DECIMAL decimal2,
  198.         GUID guid2,
  199.         BSTR* outputResult
  200.     );

  201.     virtual HRESULT STDMETHODCALLTYPE QueryInterface2(
  202.         /* [in] */ REFIID riid,
  203.         /* [annotation][iid_is][out] */
  204.         _COM_Outptr_  void** ppvObject) = 0;

  205.     virtual ULONG STDMETHODCALLTYPE AddRef2(void) = 0;

  206.     virtual ULONG STDMETHODCALLTYPE Release2(void) = 0;

  207.     virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount2(
  208.         /* [out] */ __RPC__out UINT* pctinfo) = 0;

  209.     virtual HRESULT STDMETHODCALLTYPE GetTypeInfo2(
  210.         /* [in] */ UINT iTInfo,
  211.         /* [in] */ LCID lcid,
  212.         /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo) = 0;

  213.     virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames2(
  214.         /* [in] */ __RPC__in REFIID riid,
  215.         /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
  216.         /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
  217.         /* [in] */ LCID lcid,
  218.         /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId) = 0;

  219.     virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke2(
  220.         /* [annotation][in] */
  221.         _In_  DISPID dispIdMember,
  222.         /* [annotation][in] */
  223.         _In_  REFIID riid,
  224.         /* [annotation][in] */
  225.         _In_  LCID lcid,
  226.         /* [annotation][in] */
  227.         _In_  WORD wFlags,
  228.         /* [annotation][out][in] */
  229.         _In_  DISPPARAMS* pDispParams,
  230.         /* [annotation][out] */
  231.         _Out_opt_  VARIANT* pVarResult,
  232.         /* [annotation][out] */
  233.         _Out_opt_  EXCEPINFO* pExcepInfo,
  234.         /* [annotation][out] */
  235.         _Out_opt_  UINT* puArgErr) = 0;

  236.     virtual HRESULT STDMETHODCALLTYPE GetTraceMessage(BSTR*) = 0;
  237. };
  238. extern "C" {
  239.     /* [unique][uuid][object] */
  240.     typedef interface IUnregisteredServer2_C IUnregisteredServer2_C;

  241.     typedef struct IUnregisteredServer2_CVtbl
  242.     {
  243.         BEGIN_INTERFACE

  244.             HRESULT(STDMETHODCALLTYPE* QueryInterface)(
  245.                 __RPC__in IDispatch* This,
  246.                 /* [in] */ __RPC__in REFIID riid,
  247.                 /* [annotation][iid_is][out] */
  248.                 _COM_Outptr_  void** ppvObject);

  249.         ULONG(STDMETHODCALLTYPE* AddRef)(
  250.             __RPC__in IUnregisteredServer2_C* This);

  251.         ULONG(STDMETHODCALLTYPE* Release)(
  252.             __RPC__in IUnregisteredServer2_C* This);

  253.         HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount)(
  254.             __RPC__in IUnregisteredServer2_C* This,
  255.             /* [out] */ __RPC__out UINT* pctinfo);

  256.         HRESULT(STDMETHODCALLTYPE* GetTypeInfo)(
  257.             __RPC__in IUnregisteredServer2_C* This,
  258.             /* [in] */ UINT iTInfo,
  259.             /* [in] */ LCID lcid,
  260.             /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);

  261.         HRESULT(STDMETHODCALLTYPE* GetIDsOfNames)(
  262.             __RPC__in IUnregisteredServer2_C* This,
  263.             /* [in] */ __RPC__in REFIID riid,
  264.             /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
  265.             /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
  266.             /* [in] */ LCID lcid,
  267.             /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);

  268.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke)(
  269.             IUnregisteredServer2_C* This,
  270.             /* [annotation][in] */
  271.             _In_  DISPID dispIdMember,
  272.             /* [annotation][in] */
  273.             _In_  REFIID riid,
  274.             /* [annotation][in] */
  275.             _In_  LCID lcid,
  276.             /* [annotation][in] */
  277.             _In_  WORD wFlags,
  278.             /* [annotation][out][in] */
  279.             _In_  DISPPARAMS* pDispParams,
  280.             /* [annotation][out] */
  281.             _Out_opt_  VARIANT* pVarResult,
  282.             /* [annotation][out] */
  283.             _Out_opt_  EXCEPINFO* pExcepInfo,
  284.             /* [annotation][out] */
  285.             _Out_opt_  UINT* puArgErr);

  286.         /* [local] */ HRESULT(STDMETHODCALLTYPE* DefaultMarshallingForObject)(
  287.             __RPC__in IUnregisteredServer2_C* This,
  288.             VARIANT* v,
  289.             VARIANT* v2,
  290.             VARIANT* v3
  291.             );
  292.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Map_HResultAndException)(
  293.             __RPC__in IUnregisteredServer2_C* This, BSTR* Display
  294.             );
  295.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Hello_world3)(
  296.             __RPC__in IUnregisteredServer2_C* This,
  297.             DECIMAL decimal2,
  298.             GUID guid2,
  299.             BSTR* outputResult
  300.             );

  301.         HRESULT(STDMETHODCALLTYPE* QueryInterface2)(
  302.             __RPC__in IDispatch* This,
  303.             /* [in] */ __RPC__in REFIID riid,
  304.             /* [annotation][iid_is][out] */
  305.             _COM_Outptr_  void** ppvObject);

  306.         ULONG(STDMETHODCALLTYPE* AddRef2)(
  307.             __RPC__in IUnregisteredServer2_C* This);

  308.         ULONG(STDMETHODCALLTYPE* Release2)(
  309.             __RPC__in IUnregisteredServer2_C* This);

  310.         HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount2)(
  311.             __RPC__in IUnregisteredServer2_C* This,
  312.             /* [out] */ __RPC__out UINT* pctinfo);

  313.         HRESULT(STDMETHODCALLTYPE* GetTypeInfo2)(
  314.             __RPC__in IUnregisteredServer2_C* This,
  315.             /* [in] */ UINT iTInfo,
  316.             /* [in] */ LCID lcid,
  317.             /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);

  318.         HRESULT(STDMETHODCALLTYPE* GetIDsOfNames2)(
  319.             __RPC__in IUnregisteredServer2_C* This,
  320.             /* [in] */ __RPC__in REFIID riid,
  321.             /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
  322.             /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
  323.             /* [in] */ LCID lcid,
  324.             /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);

  325.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke2)(
  326.             IUnregisteredServer2_C* This,
  327.             /* [annotation][in] */
  328.             _In_  DISPID dispIdMember,
  329.             /* [annotation][in] */
  330.             _In_  REFIID riid,
  331.             /* [annotation][in] */
  332.             _In_  LCID lcid,
  333.             /* [annotation][in] */
  334.             _In_  WORD wFlags,
  335.             /* [annotation][out][in] */
  336.             _In_  DISPPARAMS* pDispParams,
  337.             /* [annotation][out] */
  338.             _Out_opt_  VARIANT* pVarResult,
  339.             /* [annotation][out] */
  340.             _Out_opt_  EXCEPINFO* pExcepInfo,
  341.             /* [annotation][out] */
  342.             _Out_opt_  UINT* puArgErr);

  343.         /* [local] */ HRESULT(STDMETHODCALLTYPE* GetTraceMessage)(
  344.             __RPC__in IUnregisteredServer2_C* This, BSTR*
  345.             );
  346.         END_INTERFACE
  347.     } IUnregisteredServer2_CVtbl;

  348.     interface IUnregisteredServer2_C
  349.     {
  350.         CONST_VTBL struct IUnregisteredServer2_CVtbl* lpVtbl;
  351.     };

  352. #define IUnregisteredServer2_C_QueryInterface(This,riid,ppvObject) \
  353.     ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 

  354. #define IUnregisteredServer2_C_AddRef(This) \
  355.     ( (This)->lpVtbl -> AddRef(This) ) 

  356. #define IUnregisteredServer2_C_Release(This) \
  357.     ( (This)->lpVtbl -> Release(This) ) 


  358. #define IUnregisteredServer2_C_GetTypeInfoCount(This,pctinfo) \
  359.     ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) 

  360. #define IUnregisteredServer2_C_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
  361.     ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) 

  362. #define IUnregisteredServer2_C_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
  363.     ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) 

  364. #define IUnregisteredServer2_C_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
  365.     ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) 

  366. #define IUnregisteredServer2_C_DefaultMarshallingForObject(This,variant,v2,v3) \
  367.     ( (This)->lpVtbl -> DefaultMarshallingForObject(This,variant,v2,v3) ) 

  368. }
  369. int MFC_DLL_Test_UnregisteredServer2(TestParameter* ptr) {
  370.     ExportedData ED(ptr, L"MFC_DLL_Test_UnregisteredServer2");
  371.     IUnregisteredServer2_CPP* pIUnregisteredServer2_CPP;
  372.     int rv = Get_ServerInterface(ptr, 1, (PVOID*)&pIUnregisteredServer2_CPP);
  373.     if (rv < 0)return rv;

  374.     VARIANT v, v2, v3;
  375.     VariantInit(&v); VariantInit(&v2); VariantInit(&v3);
  376.     InitVariantFromInt32(0x12345, &v);
  377.     ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
  378.     pIUnregisteredServer2_CPP->DefaultMarshallingForObject(&v, &v2, &v3);
  379.     if (V_VT(&v) != VT_I8) return -3005;
  380.     ED.WriteLine(L"V_VT(&v)=%d %X ", V_VT(&v), V_I8(&v));
  381.     ED.WriteLine(L"V_VT(&v2)=%d %f ", V_VT(&v2), V_R8(&v2));

  382.     DECIMAL decimal{ };
  383.     decimal.Lo32 = 6666666; decimal.scale = 3;
  384.     GUID guid;
  385.     hr = CLSIDFromString(OLESTR("{45A82A95-6446-43F0-83B9-71E7469E14D2}"),
  386.         &guid);
  387.     if (FAILED(hr)) return  -3008;
  388.     BSTR outputResult = NULL;
  389.     pIUnregisteredServer2_CPP->Hello_world3(decimal, guid,
  390.         &outputResult);
  391.     ED.WriteLine(L"outputResult %s", outputResult);
  392.     ::SysFreeString(outputResult);

  393.     IUnregisteredServer2_C* pIUnregisteredServer2_C =
  394.         (IUnregisteredServer2_C*)pIUnregisteredServer2_CPP;
  395.     if ((void*)pIUnregisteredServer2_CPP != (void*)pIUnregisteredServer2_C) {
  396.         ED.WriteLine(L"pIUnregisteredServer2_CPP=%p", pIUnregisteredServer2_CPP);
  397.         ED.WriteLine(L"pIUnregisteredServer2_C  =%p", pIUnregisteredServer2_C);
  398.     }

  399.     VariantInit(&v);
  400.     VariantInit(&v2);
  401.     VariantInit(&v3);
  402.     InitVariantFromInt32(321, &v);
  403.     for (int aa = 0; aa < 1; aa++) {
  404.         IUnregisteredServer2_C_DefaultMarshallingForObject(
  405.             pIUnregisteredServer2_C, &v, &v2, &v3);
  406.         ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
  407.     }

  408.     BSTR Display = NULL;
  409.     hr = pIUnregisteredServer2_C->lpVtbl->Map_HResultAndException(
  410.         pIUnregisteredServer2_C, &Display);
  411.     ED.WriteLine(L"hr=0X%X", hr);
  412.     ED.WriteLine(L"Display=%s", Display);
  413.     if (Display)  ::SysFreeString(Display);
  414.     ED.WriteLine(L"sizeof(lpVtbl)=%d", sizeof(pIUnregisteredServer2_C->lpVtbl));


  415.     BSTR MyMessage = NULL;
  416.     pIUnregisteredServer2_C->lpVtbl->GetTraceMessage(
  417.         pIUnregisteredServer2_C, &MyMessage);
  418.     ED.WriteLine(L"GetTraceMessage");
  419.     ED.WriteLine(L"%s", MyMessage);
  420.     SysFreeString(MyMessage);
  421.     return 0;
  422. }
  423. /* End  MFC_DLL_Test_UnregisteredServer2 */
  424. // 2 ================================================= 3
  425. /* Begin MFC_DLL_Test_IXXXX */
  426. __interface IXXXX :public IUnregisteredServer2_CPP
  427. {
  428.     HRESULT YYYY(INT64*);
  429.     HRESULT YYYY1(BSTR*);
  430. };

  431. int MFC_DLL_Test_IXXXX(TestParameter* ptr) {
  432.     ExportedData ED(ptr, L"MFC_DLL_Test_IXXXX");
  433.     IXXXX* pIXXXX;
  434.     int rv = Get_ServerInterface(ptr, 2, (PVOID*)&pIXXXX);
  435.     if (rv < 0)return rv;
  436.     INT64 aaa;
  437.     pIXXXX->YYYY(&aaa);
  438.     ED.WriteLine(L"aaa = %d", aaa);

  439.     BSTR comment = ::SysAllocString(L" ABC ");
  440.     pIXXXX->YYYY1(&comment);
  441.     ED.WriteLine(L"comment=%s", comment);
  442.     ::SysFreeString(comment);

  443.     BSTR Trace = NULL;
  444.     pIXXXX->GetTraceMessage(&Trace);
  445.     ED.WriteLine(L"%s", Trace);
  446.     ::SysFreeString(Trace);
  447.     return 0;
  448. }
  449. /* End MFC_DLL_Test_IXXXX */
  450. #endif // _DLL














  1. LIBRARY
  2. EXPORTS
  3. MFC_DLL_Test_UnregisteredServer1          @1
  4. MFC_DLL_Test_UnregisteredServer2          @2
  5. MFC_DLL_Test_IXXXX                              @3
















  1. #If TARGET = "library" And PLATFORM = "x64" Then
  2. Option Strict On
  3. Imports System.Runtime.InteropServices
  4. <Guid("31D53FF8-4768-4A77-95E3-DC28DEBB375F")>
  5. Public Interface IUnregisterServer1
  6.     ReadOnly Property Get_Interface() As <MarshalAs(UnmanagedType.IDispatch)> Object
  7.     Sub Get_Interface2(Interface_ID As Int32, <Out> ByRef ppVoid As Object)
  8.     Sub Register_Event(<[In]()> FunctionPointer As IntPtr,
  9.      <[In], MarshalAs(UnmanagedType.BStr)> BSTR_String As String,
  10.      <Out> ByRef ID As Int32)
  11.     Sub RemoveEvent(<[In]> ID As Int32)
  12.     Sub Raise_Event(long64 As Int64)
  13.     Property MyProperty As Int32
  14.     ReadOnly Property TraceMessage As String
  15. End Interface

  16. <ComClass(
  17.     "04D9F530-CE0C-4232-8F3F-6E0A3244C715",
  18.     "31D53FF8-4768-4A77-95E3-DC28DEBB375F",
  19.     "89E4014F-3A6D-44E6-A9D3-E1CA6655B572"
  20.     )>
  21. Public Class MyUnregisterServer1 : Implements IUnregisterServer1
  22.     ReadOnly Property Get_Interface() As <MarshalAs(UnmanagedType.IUnknown)> Object _
  23.         Implements IUnregisterServer1.Get_Interface
  24.         Get
  25.             MyTrace("Get_Interface")
  26.             Return CreateObject_Chen()
  27.         End Get
  28.     End Property
  29.     Sub Get_Interface2(Interface_ID As Int32, <Out> ByRef ppVoid As Object) _
  30.             Implements IUnregisterServer1.Get_Interface2
  31.         MyTrace("Get_Interface2")
  32.         ppVoid = CreateObject_Chen()
  33.     End Sub
  34.     Sub Register_Event(
  35.      <[In]> FunctionPointer As IntPtr,
  36.      <[In], MarshalAs(UnmanagedType.BStr)> BSTR_String As String,
  37.      <Out> ByRef ID As Int32) _
  38.      Implements IUnregisterServer1.Register_Event
  39.         CppEventClassObj.Register_Event(FunctionPointer, BSTR_String, ID)
  40.         MyTrace($"Register_Event {ID}")
  41.     End Sub
  42.     Sub RemoveEvent(<[In]> ID As Int32) _
  43.         Implements IUnregisterServer1.RemoveEvent
  44.         MyTrace($"RemoveEvent {ID}")
  45.         CppEventClassObj.RemoveEvent(ID)
  46.     End Sub
  47.     Sub Raise_Event(MyTestParameter As Int64) Implements IUnregisterServer1.Raise_Event
  48.         MyTrace($"Raise_Event {MyTestParameter}")
  49.         CppEventClassObj.RaiseEventParameter = MyTestParameter
  50.         RaiseEvent Cpp_Event(Me, CppEventClassObj)
  51.     End Sub
  52.     Dim _MyProperty As Int32 = 222
  53.     Public Property MyProperty As Int32 Implements IUnregisterServer1.MyProperty
  54.         Get
  55.             MyTrace($"Get MyProperty {_MyProperty + 111}")
  56.             Return _MyProperty + 111
  57.         End Get
  58.         Set(value As Int32)
  59.             MyTrace($"Set MyProperty value= {value}")
  60.             _MyProperty = value
  61.         End Set
  62.     End Property
  63.     Public ReadOnly Property TraceMessage As String Implements IUnregisterServer1.TraceMessage
  64.         Get
  65.             TraceMessage = vbNewLine &
  66.              "==== TraceMessage(Chen Inn-Jer) ======" &
  67.              vbNewLine & _TraceMessage.ToString() &
  68.              "==== TraceMessage(Chen Inn-Jer) ======" &
  69.              vbNewLine
  70.             _TraceMessage.Clear() : TraceSteps = 0
  71.         End Get
  72.     End Property
  73.     '1----------------------------------------------------
  74.     Private TraceSteps As Int32
  75.     Private ReadOnly _TraceMessage As Text.StringBuilder
  76.     Shared MyUnregisterServer1_Object As MyUnregisterServer1
  77.     Shared Function CreateObject_Chen() As IUnregisterServer1
  78.         If MyUnregisterServer1_Object Is Nothing Then
  79.             MyUnregisterServer1_Object = New MyUnregisterServer1
  80.         End If
  81.         Return CType(MyUnregisterServer1_Object, IUnregisterServer1)
  82.     End Function
  83.     Shared Sub CreateObject3_Chen(ByRef IID As Guid,
  84.        ppvoid_temp As IntPtr, Not_Used As IntPtr)
  85.         If MyUnregisterServer1_Object Is Nothing Then
  86.             MyUnregisterServer1_Object = New MyUnregisterServer1
  87.         End If

  88.         MyUnregisterServer1_Object.MyTrace(
  89.           $"MyUnregisterServer1 IID={IID}  Not_Used = {Not_Used}")

  90.         If IID = GetType(IUnregisterServer1).GUID Then
  91.             Dim IUnregisteredInterface As IUnregisterServer1 =
  92.         CType(MyUnregisterServer1_Object, IUnregisterServer1)

  93.             Dim ppvoid As IntPtr =
  94.               Marshal.GetIUnknownForObject(IUnregisteredInterface)
  95.             Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
  96.             Exit Sub
  97.         End If
  98.         MsgBox("Error:Nothing in CreateObject3_Chen")
  99.     End Sub
  100.     Sub New()
  101.         MyBase.New()
  102.         CppEventClassObj = New CppEventClass(Me)
  103.         _TraceMessage = New Text.StringBuilder
  104.         TraceSteps = 0
  105.     End Sub
  106.     Private Class CppEventClass : Inherits EventArgs
  107.         Public RaiseEventParameter As Int64
  108.         Private EventCount As Int32
  109.         Delegate Sub DelegateForFunctionPointer(
  110.                        ByRef obj As System.Object)
  111.         Structure RegisterEvent_Struct
  112.             Dim FunctionPtr As IntPtr
  113.             Dim InputString As String
  114.             Dim ID As Int32
  115.         End Structure
  116.         Dim ObjectOwnCppEvent As MyUnregisterServer1
  117.         ReadOnly RegisterEventList As List(Of RegisterEvent_Struct)
  118.         Sub New(ObjectOwnCppEvent As MyUnregisterServer1)
  119.             Me.ObjectOwnCppEvent = ObjectOwnCppEvent
  120.             RegisterEventList = New List(Of RegisterEvent_Struct)
  121.         End Sub
  122.         Sub Register_Event(FunctionPointer As IntPtr,
  123.               BSTR_String As String, ByRef ID As Int32)
  124.             EventCount += 1
  125.             ID = EventCount
  126.             RegisterEventList.Add(New RegisterEvent_Struct With {
  127.             .FunctionPtr = FunctionPointer,
  128.             .InputString = BSTR_String,
  129.             .ID = ID
  130.             })
  131.             If RegisterEventList.Count = 1 Then
  132.                 AddHandler ObjectOwnCppEvent.Cpp_Event,
  133.                  AddressOf Handler_For_Cpp_Event
  134.             End If
  135.         End Sub
  136.         Sub RemoveEvent(ID As Int32)
  137.             For Each myitem As RegisterEvent_Struct In RegisterEventList
  138.                 If myitem.ID = ID Then
  139.                     If RegisterEventList.Count = 1 Then
  140.                         RemoveHandler ObjectOwnCppEvent.Cpp_Event,
  141.                             AddressOf Handler_For_Cpp_Event
  142.                     End If
  143.                     RegisterEventList.Remove(myitem)
  144.                     Exit Sub
  145.                 End If
  146.             Next
  147.             Throw New MyException(&HA0010002, "Error:RemoveEvent")
  148.         End Sub
  149.         Sub Handler_For_Cpp_Event(sender As Object, e As EventArgs)
  150.             For Each MyItem As RegisterEvent_Struct In RegisterEventList
  151.                 Dim DelegateForFunPtr As DelegateForFunctionPointer = CType(
  152.                       Marshal.GetDelegateForFunctionPointer(
  153.                       MyItem.FunctionPtr, GetType(DelegateForFunctionPointer)),
  154.                        DelegateForFunctionPointer)
  155.                 If DelegateForFunPtr Is Nothing Then
  156.                     MsgBox("DelegateForFunPtr Is Nothing")
  157.                 Else
  158.                     DelegateForFunPtr.Invoke(
  159.                       $"({RaiseEventParameter})" &
  160.                       "Sub Handler_For_Cpp_Event" &
  161.                       vbNewLine & MyItem.InputString)
  162.                 End If
  163.             Next
  164.         End Sub
  165.     End Class
  166.     Private ReadOnly CppEventClassObj As CppEventClass
  167.     Public Event Cpp_Event As EventHandler
  168.     Private Class MyException
  169.         Inherits Exception
  170.         Sub New(errorcode As Int32, Message As String)
  171.             MyBase.New(Message)
  172.             HResult = errorcode
  173.         End Sub
  174.     End Class
  175.     Private Sub MyTrace(msg As String)
  176.         TraceSteps += 1
  177.         _TraceMessage.AppendLine($"{TraceSteps:d2} : {msg}")
  178.     End Sub
  179. End Class
  180. '1 ================================================== 2

  181. <Guid("FDD5D79A-386E-49D0-AF60-81222A990055")>
  182. Public Interface IUnregisterServer2
  183.     '<DispId(&H11)>
  184.     Sub DefaultMarshallingForObject(
  185.                                    ByRef obj As Object,
  186.                                    ByRef obj2 As Object,
  187.                                    ByRef obj3 As Object
  188.                                    )
  189.     Sub Map_HResultAndException(
  190.     <Out, MarshalAs(UnmanagedType.BStr)>
  191.      ByRef Display As String)
  192.     Sub Hello_world3(decimal2 As System.Decimal,
  193.                      guid2 As System.Guid,
  194.     <Out, MarshalAs(UnmanagedType.BStr)> ByRef OutputResulr As String
  195.                      )
  196.     Sub QueryInterface2(
  197.      <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
  198.      <Out, MarshalAs(UnmanagedType.IUnknown)> ByRef ppVoid As Object)
  199.     Sub AddRef2()
  200.     Sub Release2()
  201.     Sub GetTypeInfoCount2(
  202.      <Out> ByRef out_UINT_pctinfo As UInt32)
  203.     Sub GetTypeInfo2(
  204.      <[In]()> itinfo As UInt32,
  205.      <[In]()> lcid As UInt32,
  206.      <Out, MarshalAs(UnmanagedType.Interface)> ByRef ppTInfo As Object)
  207.     Sub GetIDsOfNames2(
  208.       <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
  209.       <[In](), MarshalAs(UnmanagedType.LPStr)> LPOLESTR_rgszNames As String,
  210.       <[In]()> cNames As UInt32,
  211.       <[In]()> LCID_lcid As UInt32,
  212.        <Out> ByRef rgDispId As Int32)
  213.     Sub Invoke2(
  214.        <[In]()> _In_DISPID_dispIdMember As Int32,
  215.        <[In](), MarshalAs(UnmanagedType.LPStruct)> _In_REFIIDriid As Guid,
  216.        <[In]()> _In_LCID_lcid As UInt32,
  217.        <[In]()> _In_WORD_wFlags As UInt16,
  218.        <[In]()> _In_pDispParams As IntPtr,
  219.        <Out> ByRef _Out_opt_VARIANT_pVarResult As Object,
  220.        <Out> ByRef _Out_opt_pExcepInfo As IntPtr,
  221.        <Out> ByRef _Out_opt_puArgErr As UInt32)
  222.     ReadOnly Property TraceMessage As String
  223. End Interface
  224. <Guid("FDD5D79A-386E-49D0-AF60-81222A990055")>
  225. Public Interface IXXXX
  226.     Sub YYYY(<Out> ByRef ppvoid As IntPtr)
  227.     Sub YYYY1(<[In], Out, MarshalAs(UnmanagedType.BStr)> ByRef Comment As String)
  228. End Interface
  229. <ComClass("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D",
  230.           "FDD5D79A-386E-49D0-AF60-81222A990055"
  231.         )>
  232. Public Class MyUnregisterServer2
  233.     Implements IUnregisterServer2, IXXXX
  234.     Public Sub DefaultMarshallingForObject(
  235.                                           ByRef obj As Object,
  236.                                           ByRef obj2 As Object,
  237.                                           ByRef obj3 As Object
  238.                                            ) Implements IUnregisterServer2.DefaultMarshallingForObject
  239.         MyTrace($"({obj})DefaultMarshallingForObject-->&H999L")
  240.         obj = &H999L
  241.         'obj2 = New System.Decimal(666666)
  242.         obj2 = 666.6666
  243.     End Sub
  244.     Public Sub Map_HResultAndException(
  245.        <Out, MarshalAs(UnmanagedType.BStr)>
  246.        ByRef Display As String
  247.      ) Implements IUnregisterServer2.Map_HResultAndException
  248.         MyTrace("Map_HResultAndException")
  249.         'Beep()
  250.         Try
  251.             Marshal.ThrowExceptionForHR(&H80040154)
  252.         Catch ex As Exception
  253.             Display = $"msg={ex.Message}"
  254.             MyTrace(Display)
  255.             Throw New MyException(&HA1110000, ex.Message & " -- Chen")
  256.         End Try
  257.     End Sub
  258.     Public Sub Hello_world3(
  259.         decimal2 As System.Decimal,
  260.         guid As System.Guid,
  261.      <Out, MarshalAs(UnmanagedType.BStr)> ByRef outputResult As String
  262.         ) Implements IUnregisterServer2.Hello_world3
  263.         outputResult =
  264.          $" decimal= {decimal2} guid= {guid}"
  265.     End Sub
  266.     Sub QueryInterface2(
  267.      <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
  268.      <Out, MarshalAs(UnmanagedType.IUnknown)> ByRef ppVoid As Object) Implements IUnregisterServer2.QueryInterface2
  269.     End Sub
  270.     Sub AddRef2() Implements IUnregisterServer2.AddRef2

  271.     End Sub
  272.     Sub Release2() Implements IUnregisterServer2.Release2

  273.     End Sub
  274.     Sub GetTypeInfoCount2(
  275.        <Out> ByRef out_UINT_pctinfo As UInt32) Implements IUnregisterServer2.GetTypeInfoCount2
  276.     End Sub
  277.     Sub GetTypeInfo2(
  278.         itinfo As UInt32, lcid As UInt32,
  279.       <Out, MarshalAs(UnmanagedType.Interface)> ByRef ppTInfo As Object
  280.    ) Implements IUnregisterServer2.GetTypeInfo2
  281.     End Sub
  282.     Sub GetIDsOfNames2(
  283.       <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
  284.       <[In](), MarshalAs(UnmanagedType.LPStr)> LPOLESTR_rgszNames As String,
  285.       <[In]()> cNames As UInt32,
  286.       <[In]()> LCID_lcid As UInt32,
  287.       <Out> ByRef rgDispId As Int32) Implements IUnregisterServer2.GetIDsOfNames2
  288.     End Sub
  289.     Sub Invoke2(
  290.        <[In]()> _In_DISPID_dispIdMember As Int32,
  291.        <[In](), MarshalAs(UnmanagedType.LPStruct)> _In_REFIIDriid As Guid,
  292.        <[In]()> _In_LCID_lcid As UInt32,
  293.        <[In]()> _In_WORD_wFlags As UInt16,
  294.        <[In]()> _In_pDispParams As IntPtr,
  295.        <Out> ByRef _Out_opt_VARIANT_pVarResult As Object,
  296.        <Out> ByRef _Out_opt_pExcepInfo As IntPtr,
  297.        <Out> ByRef _Out_opt_puArgErr As UInt32) Implements IUnregisterServer2.Invoke2
  298.     End Sub
  299.     Public ReadOnly Property TraceMessage As String Implements IUnregisterServer2.TraceMessage
  300.         Get
  301.             TraceMessage = vbNewLine &
  302.              "==== TraceMessage(Chen Inn-Jer) 2 ======" &
  303.              vbNewLine & _TraceMessage.ToString() &
  304.              "==== TraceMessage(Chen Inn-Jer) 2 ======" &
  305.              vbNewLine
  306.             _TraceMessage.Clear() : TraceSteps = 0
  307.         End Get
  308.     End Property
  309.     Sub YYYY(<Out> ByRef intptr_obj As IntPtr) Implements IXXXX.YYYY
  310.         intptr_obj = New IntPtr(12345678)
  311.         MyTrace($"YYYY({intptr_obj})")
  312.     End Sub
  313.     Sub YYYY1(<[In], Out, MarshalAs(UnmanagedType.BStr)> ByRef Comment As String) Implements IXXXX.YYYY1
  314.         MyTrace($"YYYY1 {Comment}")
  315.         Dim MainType As Type = GetType(MyUnregisterServer2)
  316.         Dim ThisModule As Reflection.Module = MainType.Module
  317.         Dim peKind As Reflection.PortableExecutableKinds
  318.         Dim machine As Reflection.ImageFileMachine
  319.         ThisModule.GetPEKind(peKind, machine)
  320.         Comment = "This is YYYY1 in MyUnregisterServer1" &
  321.         vbNewLine & "MyLocation is " &
  322.          Reflection.Assembly.GetExecutingAssembly.Location &
  323.         vbNewLine & "FrameworkDescription is " &
  324.           Runtime.InteropServices.RuntimeInformation.FrameworkDescription &
  325.         vbNewLine & $"machine={machine} peKind={peKind}" &
  326.         vbNewLine

  327.     End Sub
  328.     '2------------------------------------------------
  329.     Dim TraceSteps As Int32
  330.     Dim _TraceMessage As Text.StringBuilder
  331.     Shared MyUnregisterServer2_Object As MyUnregisterServer2
  332.     Shared Sub CreateObject3_Chen(ByRef IID As Guid,
  333.         ppvoid_temp As IntPtr, Not_Used As IntPtr)
  334.         If MyUnregisterServer2_Object Is Nothing Then
  335.             MyUnregisterServer2_Object = New MyUnregisterServer2()
  336.         End If
  337.         MyUnregisterServer2_Object.MyTrace(
  338.           $"MyUnregisterServer2 IID={IID}  Not_Used = {Not_Used}")

  339.         If IID = GetType(IUnregisterServer2).GUID Then
  340.             Dim IUnregisteredInterface As IUnregisterServer2 =
  341.                CType(MyUnregisterServer2_Object,
  342.                IUnregisterServer2)
  343.             Dim ppvoid As IntPtr = Marshal.GetIUnknownForObject(IUnregisteredInterface)
  344.             Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
  345.             Exit Sub
  346.         ElseIf IID = GetType(IXXXX).GUID Then
  347.             Dim IXXXXInterface As IXXXX =
  348.                 CType(MyUnregisterServer2_Object,
  349.                 IXXXX)
  350.             Dim ppvoid As IntPtr = Marshal.GetIUnknownForObject(IXXXXInterface)
  351.             Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
  352.             Exit Sub
  353.         End If
  354.         MsgBox("Error:Nothing")
  355.     End Sub
  356.     Sub New()
  357.         MyBase.New()
  358.         _TraceMessage = New Text.StringBuilder(5 << 20)
  359.         TraceSteps = 0
  360.     End Sub
  361.     Private Class MyException
  362.         Inherits Exception
  363.         Sub New(errorcode As Int32, Message As String)
  364.             MyBase.New(Message)
  365.             HResult = errorcode
  366.         End Sub
  367.     End Class
  368.     Private Sub MyTrace(msg As String)
  369.         TraceSteps += 1
  370.         _TraceMessage.AppendLine($"{TraceSteps:d2} : {msg}")
  371.     End Sub

  372. End Class
  373. #End If
























  1. #include "pch.h"
  2. #include <stdio.h>
  3. #include <objbase.h>
  4. #include <windows.h>
  5. #include <Combaseapi.h>
  6. #include "oleauto.h"
  7. #include "propvarutil.h"
  8. #include "wtypes.h"
  9. #include <ctime>
  10. #include <exception>
  11. #include <typeinfo>
  12. #include "TestParameter.h"

  13. #if defined(_M_AMD64) && defined(_WIN64) && defined(_WINDOWS) && \
  14.     defined(_USRDLL) && _MSVC_LANG >= 202002L 

  15. extern "C" /* exported functions */ {
  16.     int CPP_DLL_Test_UnregisteredServer1(TestParameter*);
  17.     int CPP_DLL_Test_UnregisteredServer2(TestParameter*);
  18.     int CPP_DLL_Test_IXXXX(TestParameter*);
  19. }

  20. IUnknown* pIUnknown;
  21. HRESULT hr;

  22. template <class T> concept  Is_BSTR_v = std::is_convertible_v<T, BSTR>;

  23. template <class T> concept  Is_LPCOLESTR_v = std::is_convertible_v<LPCOLESTR, T>;

  24. template <typename T>
  25. struct ServerInfo_Struct {
  26.     T AssemblyPath;
  27.     T TypeFullName;
  28.     T CreationMethod;
  29.     T CLSID;
  30.     T IID;
  31.     ServerInfo_Struct(T t1, T t2, T t3, T t4, T t5) :
  32.         AssemblyPath(t1),
  33.         TypeFullName(t2),
  34.         CreationMethod(t3),
  35.         CLSID(t4),
  36.         IID(t5) {
  37.     }
  38.     ServerInfo_Struct& operator=(ServerInfo_Struct&) = delete;
  39.     ServerInfo_Struct(const ServerInfo_Struct&) = delete;

  40.     ~ServerInfo_Struct() requires Is_BSTR_v<T> {
  41.         if (0 == strcmp(typeid(T).name(), typeid(BSTR).name())) {
  42.             printf("std::is_convertible_v< %s , %s >\n",
  43.                 typeid(T).name(), typeid(BSTR).name());
  44.         }
  45.         else printf("===> Error:%s\n", typeid(T).name());

  46.         ::SysFreeString((wchar_t*)AssemblyPath);
  47.         ::SysFreeString((wchar_t*)TypeFullName);
  48.         ::SysFreeString((wchar_t*)CreationMethod);
  49.         ::SysFreeString((wchar_t*)CLSID);
  50.         ::SysFreeString((wchar_t*)IID);
  51.     }

  52.     ~ServerInfo_Struct()requires Is_LPCOLESTR_v<T> {
  53.         puts(typeid(T).name());
  54.         if (0 == strcmp(typeid(LPCOLESTR).name(), typeid(T).name())) {
  55.             printf("std::is_convertible_v< %s , %s >\n",
  56.                 typeid(LPCOLESTR).name(), typeid(T).name());
  57.         }
  58.         else printf("===> Error:%s\n", typeid(T).name());
  59.     }

  60. };
  61. template ServerInfo_Struct<LPCOLESTR>;
  62. template ServerInfo_Struct<BSTR>;
  63. #ifdef _DEBUG
  64. const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
  65.     "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Debug\\NotRegisteredServer.dll"
  66. );
  67. #else
  68. const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
  69.     "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Release\\NotRegisteredServer.dll"
  70. );
  71. #endif


  72. ServerInfo_Struct<LPCOLESTR> My_Server_string[] = {
  73.   {
  74.      MyServerName,
  75.      (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer1"),
  76.      (LPCOLESTR)OLESTR("CreateObject3_Chen"),
  77.      (LPCOLESTR)OLESTR("04D9F530-CE0C-4232-8F3F-6E0A3244C715"),
  78.      (LPCOLESTR)OLESTR("31D53FF8-4768-4A77-95E3-DC28DEBB375F")
  79.   },{
  80.      MyServerName,
  81.      (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
  82.      (LPCOLESTR)OLESTR("CreateObject3_Chen"),
  83.      (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
  84.      (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
  85.   },{
  86.      MyServerName,
  87.      (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
  88.      (LPCOLESTR)OLESTR("CreateObject3_Chen"),
  89.      (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
  90.      (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
  91.   }
  92. };
  93. int Get_ServerInterface(TestParameter* ptr, int interfaceID
  94.     , PVOID* pRetVal) {
  95.     ICreationInstance* Ptr_Creation_Instance =
  96.         (ICreationInstance*)ptr->ptr_to_Interface;
  97.     ServerInfo_Struct<LPCOLESTR>& MyServerString = My_Server_string[interfaceID];
  98.     ServerInfo_Struct<BSTR> My_Server{
  99.         SysAllocString(ToFullPath(ptr->PathRoot,MyServerString.AssemblyPath)),
  100.         SysAllocString(MyServerString.TypeFullName),
  101.         SysAllocString(MyServerString.CreationMethod),
  102.         SysAllocString(MyServerString.CLSID),
  103.         SysAllocString(MyServerString.IID)
  104.     };
  105.     hr = Ptr_Creation_Instance->Get_Interface3(&My_Server, (PVOID*)&pIUnknown);
  106.     if (FAILED(hr))return -31;
  107.     IID myiid2;
  108.     hr = IIDFromString(AddCurlyBracket(My_Server.IID), &myiid2);
  109.     if (FAILED(hr))return -32;
  110.     hr = pIUnknown->QueryInterface(myiid2, pRetVal);
  111.     if (FAILED(hr))return -33;
  112.     return 0;
  113. }
  114. /* Begin CPP_DLL_Test_UnregisteredServer1 */
  115. void This_Delegate_will_be_called_While_RaiseEvent(VARIANTARG VAR) {
  116.     ExportedData::MySelf()->WriteLine(L"This_Delegate_will_be_called_While_RaiseEvent(VT_BSTR=%d V_VT(&VAR)=%d)",
  117.         VT_BSTR, V_VT(&VAR));
  118.     ExportedData::MySelf()->WriteLine(L"<@%s@>", V_BSTR(&VAR));
  119. }
  120. __interface IUnregisteredServer1 :IDispatch
  121. {
  122.     HRESULT Get_Interface(PVOID*);
  123.     HRESULT Get_Interface2(long, VARIANTARG*);
  124.     HRESULT Register_Event(void (*)(VARIANT), BSTR, INT32* ID);
  125.     HRESULT RemoveEvent(INT32 ID);
  126.     HRESULT Raise_Event(LONG64);
  127.     HRESULT Get_MyProperty(INT32*);
  128.     HRESULT Put_MyProperty(INT32 pRetVal);
  129.     HRESULT GetTraceMessage(BSTR*);
  130. };
  131. int CPP_DLL_Test_UnregisteredServer1(TestParameter* ptr) {
  132.     ExportedData ED(ptr, L"CPP_DLL_Test_UnregisteredServer1");
  133.     IUnregisteredServer1* pIUnregisteredServer1;
  134.     int rv = Get_ServerInterface(ptr, 0, (PVOID*)&pIUnregisteredServer1);
  135.     if (rv < 0)return rv;

  136.     INT32 _INT32 = 777;
  137.     ED.WriteLine(L"(%d)", _INT32);
  138.     pIUnregisteredServer1->Get_MyProperty(&_INT32);
  139.     ED.WriteLine(L"(%d)", _INT32);

  140.     INT32 EventID[3]{};
  141.     BSTR MyString_BSTR = SysAllocString(L"Register_Event(&This_Delegate_will_be_called_While_RaiseEvent, MyString_BSTR)");
  142.     for (INT64 aa = 21; aa < 25; aa++) {
  143.         for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
  144.             pIUnregisteredServer1->Register_Event(&This_Delegate_will_be_called_While_RaiseEvent,
  145.                 MyString_BSTR, &EventID[bb]);
  146.         }
  147.         pIUnregisteredServer1->Raise_Event(aa);
  148.         for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
  149.             pIUnregisteredServer1->RemoveEvent(EventID[bb]);
  150.         }
  151.     }
  152.     ::SysFreeString(MyString_BSTR);

  153.     IUnknown* _ptr2_;
  154.     pIUnregisteredServer1->Get_Interface((PVOID*)&_ptr2_);
  155.     if (pIUnknown != _ptr2_) {
  156.         ED.WriteLine(L"Error1:%p", pIUnknown);
  157.         ED.WriteLine(L"Error1:%p", _ptr2_);
  158.     }
  159.     VARIANT _variant;
  160.     VariantInit(&_variant);
  161.     pIUnregisteredServer1->Get_Interface2(2, &_variant);
  162.     if (V_VT(&_variant) != VT_UNKNOWN) {
  163.         ED.WriteLine(L"error: V_VT(&_variant)=%d", V_VT(&_variant));
  164.     }
  165.     _ptr2_ = V_DISPATCH(&_variant);
  166.     if (pIUnknown != _ptr2_) {
  167.         ED.WriteLine(L"Error2:%p", pIUnknown);
  168.         ED.WriteLine(L"Error2:%p", _ptr2_);
  169.     }

  170.     BSTR MyMessage = NULL;
  171.     pIUnregisteredServer1->GetTraceMessage(&MyMessage);
  172.     ED.WriteLine(L"GetTraceMessage");
  173.     ED.WriteLine(L"%s", MyMessage);
  174.     SysFreeString(MyMessage);
  175.     return 0;
  176. }
  177. /* End  CPP_DLL_Test_UnregisteredServer1 */
  178. // 1 ======================================================= 2
  179. /* Begin CPP_DLL_Test_UnregisteredServer2 */
  180. __interface IUnregisteredServer2_CPP :public IDispatch
  181. {
  182. public:
  183.     HRESULT DefaultMarshallingForObject(VARIANT* v, VARIANT* v2, VARIANT* v3);
  184.     HRESULT Map_HResultAndException(BSTR* display);
  185.     HRESULT Hello_world3(
  186.         DECIMAL decimal2,
  187.         GUID guid2,
  188.         BSTR* outputResult
  189.     );

  190.     virtual HRESULT STDMETHODCALLTYPE QueryInterface2(
  191.         /* [in] */ REFIID riid,
  192.         /* [annotation][iid_is][out] */
  193.         _COM_Outptr_  void** ppvObject) = 0;

  194.     virtual ULONG STDMETHODCALLTYPE AddRef2(void) = 0;

  195.     virtual ULONG STDMETHODCALLTYPE Release2(void) = 0;

  196.     virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount2(
  197.         /* [out] */ __RPC__out UINT* pctinfo) = 0;

  198.     virtual HRESULT STDMETHODCALLTYPE GetTypeInfo2(
  199.         /* [in] */ UINT iTInfo,
  200.         /* [in] */ LCID lcid,
  201.         /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo) = 0;

  202.     virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames2(
  203.         /* [in] */ __RPC__in REFIID riid,
  204.         /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
  205.         /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
  206.         /* [in] */ LCID lcid,
  207.         /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId) = 0;

  208.     virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke2(
  209.         /* [annotation][in] */
  210.         _In_  DISPID dispIdMember,
  211.         /* [annotation][in] */
  212.         _In_  REFIID riid,
  213.         /* [annotation][in] */
  214.         _In_  LCID lcid,
  215.         /* [annotation][in] */
  216.         _In_  WORD wFlags,
  217.         /* [annotation][out][in] */
  218.         _In_  DISPPARAMS* pDispParams,
  219.         /* [annotation][out] */
  220.         _Out_opt_  VARIANT* pVarResult,
  221.         /* [annotation][out] */
  222.         _Out_opt_  EXCEPINFO* pExcepInfo,
  223.         /* [annotation][out] */
  224.         _Out_opt_  UINT* puArgErr) = 0;

  225.     virtual HRESULT STDMETHODCALLTYPE GetTraceMessage(BSTR*) = 0;
  226. };
  227. extern "C" {
  228.     /* [unique][uuid][object] */
  229.     typedef interface IUnregisteredServer2_C IUnregisteredServer2_C;

  230.     typedef struct IUnregisteredServer2_CVtbl
  231.     {
  232.         BEGIN_INTERFACE

  233.             HRESULT(STDMETHODCALLTYPE* QueryInterface)(
  234.                 __RPC__in IDispatch* This,
  235.                 /* [in] */ __RPC__in REFIID riid,
  236.                 /* [annotation][iid_is][out] */
  237.                 _COM_Outptr_  void** ppvObject);

  238.         ULONG(STDMETHODCALLTYPE* AddRef)(
  239.             __RPC__in IUnregisteredServer2_C* This);

  240.         ULONG(STDMETHODCALLTYPE* Release)(
  241.             __RPC__in IUnregisteredServer2_C* This);

  242.         HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount)(
  243.             __RPC__in IUnregisteredServer2_C* This,
  244.             /* [out] */ __RPC__out UINT* pctinfo);

  245.         HRESULT(STDMETHODCALLTYPE* GetTypeInfo)(
  246.             __RPC__in IUnregisteredServer2_C* This,
  247.             /* [in] */ UINT iTInfo,
  248.             /* [in] */ LCID lcid,
  249.             /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);

  250.         HRESULT(STDMETHODCALLTYPE* GetIDsOfNames)(
  251.             __RPC__in IUnregisteredServer2_C* This,
  252.             /* [in] */ __RPC__in REFIID riid,
  253.             /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
  254.             /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
  255.             /* [in] */ LCID lcid,
  256.             /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);

  257.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke)(
  258.             IUnregisteredServer2_C* This,
  259.             /* [annotation][in] */
  260.             _In_  DISPID dispIdMember,
  261.             /* [annotation][in] */
  262.             _In_  REFIID riid,
  263.             /* [annotation][in] */
  264.             _In_  LCID lcid,
  265.             /* [annotation][in] */
  266.             _In_  WORD wFlags,
  267.             /* [annotation][out][in] */
  268.             _In_  DISPPARAMS* pDispParams,
  269.             /* [annotation][out] */
  270.             _Out_opt_  VARIANT* pVarResult,
  271.             /* [annotation][out] */
  272.             _Out_opt_  EXCEPINFO* pExcepInfo,
  273.             /* [annotation][out] */
  274.             _Out_opt_  UINT* puArgErr);

  275.         /* [local] */ HRESULT(STDMETHODCALLTYPE* DefaultMarshallingForObject)(
  276.             __RPC__in IUnregisteredServer2_C* This,
  277.             VARIANT* v,
  278.             VARIANT* v2,
  279.             VARIANT* v3
  280.             );
  281.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Map_HResultAndException)(
  282.             __RPC__in IUnregisteredServer2_C* This, BSTR* Display
  283.             );
  284.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Hello_world3)(
  285.             __RPC__in IUnregisteredServer2_C* This,
  286.             DECIMAL decimal2,
  287.             GUID guid2,
  288.             BSTR* outputResult
  289.             );

  290.         HRESULT(STDMETHODCALLTYPE* QueryInterface2)(
  291.             __RPC__in IDispatch* This,
  292.             /* [in] */ __RPC__in REFIID riid,
  293.             /* [annotation][iid_is][out] */
  294.             _COM_Outptr_  void** ppvObject);

  295.         ULONG(STDMETHODCALLTYPE* AddRef2)(
  296.             __RPC__in IUnregisteredServer2_C* This);

  297.         ULONG(STDMETHODCALLTYPE* Release2)(
  298.             __RPC__in IUnregisteredServer2_C* This);

  299.         HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount2)(
  300.             __RPC__in IUnregisteredServer2_C* This,
  301.             /* [out] */ __RPC__out UINT* pctinfo);

  302.         HRESULT(STDMETHODCALLTYPE* GetTypeInfo2)(
  303.             __RPC__in IUnregisteredServer2_C* This,
  304.             /* [in] */ UINT iTInfo,
  305.             /* [in] */ LCID lcid,
  306.             /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);

  307.         HRESULT(STDMETHODCALLTYPE* GetIDsOfNames2)(
  308.             __RPC__in IUnregisteredServer2_C* This,
  309.             /* [in] */ __RPC__in REFIID riid,
  310.             /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
  311.             /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
  312.             /* [in] */ LCID lcid,
  313.             /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);

  314.         /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke2)(
  315.             IUnregisteredServer2_C* This,
  316.             /* [annotation][in] */
  317.             _In_  DISPID dispIdMember,
  318.             /* [annotation][in] */
  319.             _In_  REFIID riid,
  320.             /* [annotation][in] */
  321.             _In_  LCID lcid,
  322.             /* [annotation][in] */
  323.             _In_  WORD wFlags,
  324.             /* [annotation][out][in] */
  325.             _In_  DISPPARAMS* pDispParams,
  326.             /* [annotation][out] */
  327.             _Out_opt_  VARIANT* pVarResult,
  328.             /* [annotation][out] */
  329.             _Out_opt_  EXCEPINFO* pExcepInfo,
  330.             /* [annotation][out] */
  331.             _Out_opt_  UINT* puArgErr);

  332.         /* [local] */ HRESULT(STDMETHODCALLTYPE* GetTraceMessage)(
  333.             __RPC__in IUnregisteredServer2_C* This, BSTR*
  334.             );
  335.         END_INTERFACE
  336.     } IUnregisteredServer2_CVtbl;

  337.     interface IUnregisteredServer2_C
  338.     {
  339.         CONST_VTBL struct IUnregisteredServer2_CVtbl* lpVtbl;
  340.     };

  341. #define IUnregisteredServer2_C_QueryInterface(This,riid,ppvObject) \
  342.     ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 

  343. #define IUnregisteredServer2_C_AddRef(This) \
  344.     ( (This)->lpVtbl -> AddRef(This) ) 

  345. #define IUnregisteredServer2_C_Release(This) \
  346.     ( (This)->lpVtbl -> Release(This) ) 


  347. #define IUnregisteredServer2_C_GetTypeInfoCount(This,pctinfo) \
  348.     ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) 

  349. #define IUnregisteredServer2_C_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
  350.     ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) 

  351. #define IUnregisteredServer2_C_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
  352.     ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) 

  353. #define IUnregisteredServer2_C_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
  354.     ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) 

  355. #define IUnregisteredServer2_C_DefaultMarshallingForObject(This,variant,v2,v3) \
  356.     ( (This)->lpVtbl -> DefaultMarshallingForObject(This,variant,v2,v3) ) 

  357. }
  358. int CPP_DLL_Test_UnregisteredServer2(TestParameter* ptr) {
  359.     ExportedData ED(ptr, L"CPP_DLL_Test_UnregisteredServer2");
  360.     IUnregisteredServer2_CPP* pIUnregisteredServer2_CPP;
  361.     int rv = Get_ServerInterface(ptr, 1, (PVOID*)&pIUnregisteredServer2_CPP);
  362.     if (rv < 0)return rv;

  363.     VARIANT v, v2, v3;
  364.     VariantInit(&v); VariantInit(&v2); VariantInit(&v3);
  365.     InitVariantFromInt32(0x12345, &v);
  366.     ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
  367.     pIUnregisteredServer2_CPP->DefaultMarshallingForObject(&v, &v2, &v3);
  368.     if (V_VT(&v) != VT_I8) return -3005;
  369.     ED.WriteLine(L"V_VT(&v)=%d %X ", V_VT(&v), V_I8(&v));
  370.     ED.WriteLine(L"V_VT(&v2)=%d %f ", V_VT(&v2), V_R8(&v2));

  371.     DECIMAL d{ };
  372.     GUID g;
  373.     d.Lo32 = 6666666; d.scale = 3;

  374.     hr = CLSIDFromString(OLESTR("{45A82A95-6446-43F0-83B9-71E7469E14D2}"),
  375.         &g);
  376.     if (FAILED(hr)) return  -3008;
  377.     BSTR outputResult = NULL;
  378.     pIUnregisteredServer2_CPP->Hello_world3(d, g,
  379.         &outputResult);
  380.     ED.WriteLine(L"outputResult %s", outputResult);
  381.     ::SysFreeString(outputResult);

  382.     IUnregisteredServer2_C* pIUnregisteredServer2_C =
  383.         (IUnregisteredServer2_C*)pIUnregisteredServer2_CPP;
  384.     if ((void*)pIUnregisteredServer2_CPP != (void*)pIUnregisteredServer2_C) {
  385.         ED.WriteLine(L"pIUnregisteredServer2_CPP=%p", pIUnregisteredServer2_CPP);
  386.         ED.WriteLine(L"pIUnregisteredServer2_C  =%p", pIUnregisteredServer2_C);
  387.     }

  388.     VariantInit(&v);
  389.     VariantInit(&v2);
  390.     VariantInit(&v3);
  391.     InitVariantFromInt32(321, &v);
  392.     for (int aa = 0; aa < 1; aa++) {
  393.         IUnregisteredServer2_C_DefaultMarshallingForObject(
  394.             pIUnregisteredServer2_C, &v, &v2, &v3);
  395.         ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
  396.     }

  397.     BSTR Display = NULL;
  398.     hr = pIUnregisteredServer2_C->lpVtbl->Map_HResultAndException(
  399.         pIUnregisteredServer2_C, &Display);
  400.     ED.WriteLine(L"hr=0X%X", hr);
  401.     ED.WriteLine(L"Display=%s", Display);
  402.     if (Display)  ::SysFreeString(Display);
  403.     ED.WriteLine(L"sizeof(lpVtbl)=%d", sizeof(pIUnregisteredServer2_C->lpVtbl));


  404.     BSTR MyMessage = NULL;
  405.     pIUnregisteredServer2_C->lpVtbl->GetTraceMessage(
  406.         pIUnregisteredServer2_C, &MyMessage);
  407.     ED.WriteLine(L"GetTraceMessage");
  408.     ED.WriteLine(L"%s", MyMessage);
  409.     SysFreeString(MyMessage);
  410.     return 0;
  411. }
  412. /* End  CPP_DLL_Test_UnregisteredServer2 */
  413. // 2 ================================================= 3
  414. /* Begin CPP_DLL_Test_IXXXX */
  415. __interface IXXXX :public IUnregisteredServer2_CPP
  416. {
  417.     HRESULT YYYY(INT64*);
  418.     HRESULT YYYY1(BSTR*);
  419. };

  420. int CPP_DLL_Test_IXXXX(TestParameter* ptr) {
  421.     ExportedData ED(ptr, L"CPP_DLL_Test_IXXXX");
  422.     IXXXX* pIXXXX;
  423.     int rv = Get_ServerInterface(ptr, 2, (PVOID*)&pIXXXX);
  424.     if (rv < 0)return rv;
  425.     INT64 aaa;
  426.     pIXXXX->YYYY(&aaa);
  427.     ED.WriteLine(L"aaa = %d", aaa);

  428.     BSTR comment = ::SysAllocString(L" ABC ");
  429.     pIXXXX->YYYY1(&comment);
  430.     ED.WriteLine(L"comment=%s", comment);
  431.     ::SysFreeString(comment);

  432.     BSTR Trace = NULL;
  433.     pIXXXX->GetTraceMessage(&Trace);
  434.     ED.WriteLine(L"%s", Trace);
  435.     ::SysFreeString(Trace);
  436.     return 0;
  437. }
  438. /* End CPP_DLL_Test_IXXXX */
  439. #endif 











  1. LIBRARY
  2. EXPORTS
  3. CPP_DLL_Test_UnregisteredServer1          @1
  4. CPP_DLL_Test_UnregisteredServer2          @2
  5. CPP_DLL_Test_IXXXX                              @3









留言

這個網誌中的熱門文章

Marshalling

Calling a C# WPF library from C++