Marshalling II
Updated on July 29,2025
- #include <iostream>
- namespace Chen { int My_Console_Main(const wchar_t* comment); }
- int main()
- {
- std::cout << "Hello World!\n";
- return Chen::My_Console_Main(L"Startup project with =====> MFC");
- }
Updated on July 29,2025
- #include "Windows.h"
- #include "shlwapi.h"
- #include "Psapi.h"
- #include "stdexcept"
- #include "stdarg.h"
- #include "stdio.h"
- #define AfxLoadLibrary LoadLibraryW
- #define AfxFreeLibrary FreeLibrary
- #if defined(_M_AMD64) && defined(_WIN64) && defined(_CONSOLE) && \
- _MSVC_LANG >= 201703L
- #include "TestParameter.h"
- namespace Chen {
- int My_Console_Main(const wchar_t* comment);
- #define CreationInstance_clsid OLESTR("91DD12FD-4DBD-4B83-AC40-439E3B6393A1")
- #define CreationInstance_iid OLESTR("85927839-0BB2-423B-97D6-89A2D4002519")
- #ifdef _DEBUG
- const LPCWSTR MyDllname =
- L"MFC_DLL_Test_Marshalling\\x64\\Debug\\MFCDLLTestMarshalling.dll";
- const LPCWSTR MyDllname2 =
- L"CPP_Dll_Test_Marshalling\\x64\\Debug\\CPP_Dll_Test_Marshalling.dll";
- #else
- const LPCWSTR MyDllname =
- L"MFC_DLL_Test_Marshalling\\x64\\Release\\MFCDLLTestMarshalling.dll";
- const LPCWSTR MyDllname2 =
- L"CPP_Dll_Test_Marshalling\\x64\\Release\\CPP_Dll_Test_Marshalling.dll";
- #endif // DEBUG
- typedef struct {
- LPCWSTR DLL_Path;
- LPCSTR ProcName;
- BOOL MFC_DLL;
- } ClientInfo_Struct;
- ClientInfo_Struct ClientInfo[]{
- {
- MyDllname,
- "MFC_DLL_Test_UnregisteredServer1",
- true
- },{
- MyDllname,
- "MFC_DLL_Test_UnregisteredServer2",
- true
- },{
- MyDllname,
- "MFC_DLL_Test_IXXXX",
- true
- },{
- MyDllname2,
- "CPP_DLL_Test_UnregisteredServer1",
- false
- },{
- MyDllname2,
- "CPP_DLL_Test_UnregisteredServer2",
- false
- },{
- MyDllname2,
- "CPP_DLL_Test_IXXXX",
- false
- }
- };
- void Get_CreationInstance_To_Create_UnregisteredServer(
- _In_ LPCOLESTR CLSID_String,
- _In_ LPCOLESTR IID_String);
- void My_Test_Function();
- void ReleaseResource();
- void ErrorMessage(const CHAR* ERR_MSG);
- namespace Debug_namespace {
- inline namespace FileForDebug_namespace {
- const size_t BufferSize_File = 5UI64 << 20;
- class FileForDebug {
- bool OnDebug;
- bool IsSave;
- bool TooLarge;
- WCHAR previousCHAR[BufferSize_File];
- WCHAR* pStart_Previous;
- size_t ReadSize, WriteSize;
- public:
- FileForDebug();
- void compareData(const wchar_t* pStart, int size);
- void Save();
- };
- FileForDebug* MyFileForDebug;
- }
- inline namespace ExportedData_namespace {
- const size_t BufferSize_Line = 1500UI64;
- WCHAR MyLine[BufferSize_Line + 3];
- size_t size;
- va_list My_va_list;
- void OutputFunction(const WCHAR* str, int size) {
- wprintf(L"%s", str);
- MyFileForDebug->compareData(str, size);
- }
- void Ellipsis() {
- size = BufferSize_Line - 1;
- *(MyLine + size++) = L'.';
- *(MyLine + size++) = L'.';
- *(MyLine + size++) = L'.';
- *(MyLine + size) = L'\0';
- OutputFunction(MyLine, (int)size);
- // printf("size= %I64u BufferSize_Line=%I64u\n",
- // size, BufferSize_Line);system("pause");
- }
- void AppendNewline() {
- *(MyLine + size++) = L'\r';
- *(MyLine + size++) = L'\n';
- *(MyLine + size) = L'\0';
- OutputFunction(MyLine, (int)size);
- }
- void My_Write_Line(const WCHAR* format, va_list va_list) {
- size = _vsnwprintf_s(MyLine, BufferSize_Line, _TRUNCATE, format, va_list);
- if (size >= BufferSize_Line) Ellipsis();
- else AppendNewline();
- }
- void MyWriteLine(const WCHAR* format, ...) {
- va_start(My_va_list, format);
- My_Write_Line(format, My_va_list);
- va_end(My_va_list);
- }
- void My_Write(const WCHAR* format, va_list va_list) {
- size = _vsnwprintf_s(MyLine, BufferSize_Line, _TRUNCATE, format, va_list);
- if (size >= BufferSize_Line) Ellipsis();
- else OutputFunction(MyLine, (int)size);
- }
- void MyWrite(const WCHAR* format, ...) {
- va_start(My_va_list, format);
- My_Write(format, My_va_list);
- va_end(My_va_list);
- }
- }
- }
- using Debug_namespace::MyWriteLine;
- using Debug_namespace::MyFileForDebug;
- using Debug_namespace::FileForDebug;
- class MyException : public std::exception {
- const char* ExceptionString;
- public:
- int errorNo;
- MyException(const char* Exception_MSG, int errorNo) :
- ExceptionString(Exception_MSG), errorNo(errorNo) {
- }
- virtual const char* what()const;
- };
- const char* MyException::what()const { return ExceptionString; }
- #define NTFS_MAX_PATH ( 32llu <<10)
- WCHAR Current_Directory[NTFS_MAX_PATH];
- WCHAR ProcessImageFileName[NTFS_MAX_PATH];
- WCHAR ModuleFileName[NTFS_MAX_PATH];
- WCHAR APP_Dir[NTFS_MAX_PATH];
- WCHAR MyPathRoot[NTFS_MAX_PATH];
- HANDLE hThread;
- DWORD ProcessID;
- HANDLE hProcess;
- HRESULT hr;
- IUnknown* pIUnknown;
- ICreationInstance* pICreationInstance;
- const bool b_FreeLibrary = false; //true;
- const size_t hModuleSize = 1000;
- HMODULE hModule_Chen[hModuleSize + (b_FreeLibrary ? 0 : ARRAYSIZE(ClientInfo))];
- HMODULE* phModule_Chen;
- WCHAR ModuleName[NTFS_MAX_PATH];
- void MyEnumModules() {
- if (hProcess) {
- DWORD cbNeeded = 0;
- if (!K32EnumProcessModules(hProcess, phModule_Chen,
- hModuleSize * sizeof(HMODULE), &cbNeeded)) {
- ErrorMessage("error: K32EnumProcessModules ");
- }
- for (int i = 0; i < hModuleSize && hModule_Chen[i]; i++) {
- GetModuleFileNameExW(hProcess, hModule_Chen[i],
- ModuleName, NTFS_MAX_PATH);
- printf("%2i %p %S\n", i, hModule_Chen[i], ModuleName);
- }
- int aa = 0;
- for (HMODULE* pLoadedDLL = hModule_Chen; pLoadedDLL < phModule_Chen; pLoadedDLL++) {
- BOOL FreeLib_OK = (ClientInfo[aa].MFC_DLL ?
- AfxFreeLibrary : FreeLibrary)(*pLoadedDLL);
- LPCWSTR DLL_Name = ClientInfo[aa].DLL_Path;
- if (FreeLib_OK)
- MyWriteLine(L" FreeLibrary OK %s\n", DLL_Name);
- else
- MyWriteLine(L" error: FreeLibrary %s\n", DLL_Name);
- aa++;
- }
- phModule_Chen = hModule_Chen;
- printf("hModuleCount=%I64i\n", cbNeeded / sizeof(HMODULE));
- if (K32EnumProcessModules(hProcess, NULL, 0, &cbNeeded))
- printf("hModuleCount=%I64i\n", cbNeeded / sizeof(HMODULE));
- }
- }
- void AppInitialize() {
- #define MyFMT "\t%S\n"
- GetCurrentDirectoryW(NTFS_MAX_PATH, Current_Directory);
- printf("CurrentDir =" MyFMT, Current_Directory);
- phModule_Chen = hModule_Chen;
- hThread = GetCurrentThread();
- ProcessID = GetProcessIdOfThread(hThread);
- hProcess = OpenProcess(
- PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, ProcessID);
- DWORD size = NTFS_MAX_PATH;
- if (!QueryFullProcessImageNameW(hProcess, 0, ProcessImageFileName, &size))
- throw MyException("QueryFullProcessImageNameW", -1004);
- printf("APPFullName=" MyFMT, ProcessImageFileName);
- if (GetModuleFileNameW(NULL, ModuleFileName, NTFS_MAX_PATH) >= NTFS_MAX_PATH)
- throw MyException("GetModuleFileNameW", -1001);
- printf("ModuleFileName=" MyFMT, ModuleFileName);
- wcscpy_s(APP_Dir, NTFS_MAX_PATH, ProcessImageFileName);
- PathCchRemoveFileSpec(APP_Dir, NTFS_MAX_PATH);
- printf("APP_Dir= " MyFMT, APP_Dir);
- hr = PathCchCombine(MyPathRoot, NTFS_MAX_PATH, APP_Dir, L"..\\..\\..\\");
- if (FAILED(hr))throw MyException("PathCchCombine", -1002);
- PathCchAddBackslash(MyPathRoot, NTFS_MAX_PATH);
- printf("MyPathRoot=" MyFMT, MyPathRoot);
- // ---> For debug
- printf("RelativePath=\t%100S\n", MyDllname);
- const WCHAR* pFullPath = ToFullPath(MyPathRoot, MyDllname);
- if (PathFileExistsW(pFullPath))
- printf(" FullPath= \t%100S\n", pFullPath);
- else printf("file not exist\t%100S\n", MyDllname);
- // ---> For debug
- system("pause");
- }
- int My_Console_Main(const wchar_t* comment) {
- printf("%S\n", comment);
- printf("CommandLine=%s\n", GetCommandLineA());
- AppInitialize();
- try {
- MyFileForDebug = new FileForDebug();
- hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
- if (FAILED(hr))throw MyException("CoInitializeEx", -1);
- hr = OleInitialize(NULL);
- if (FAILED(hr))throw MyException("OleInitialize", -2);
- Get_CreationInstance_To_Create_UnregisteredServer(
- CreationInstance_clsid, CreationInstance_iid);
- for (int ff = 0; ff < 3; ff++) {
- My_Test_Function();
- MyEnumModules();
- system("pause");
- }
- OleUninitialize();
- CoUninitialize();
- MyFileForDebug->Save();
- ReleaseResource();
- system("pause");
- }
- catch (const MyException& ex) {
- printf("errorNo=%d\n", ex.errorNo);
- ErrorMessage(ex.what());
- return ex.errorNo;
- }
- catch (const std::exception& ex) {
- ErrorMessage(ex.what());
- return -1000;
- }
- return 0;
- }
- void Get_CreationInstance_To_Create_UnregisteredServer(
- _In_ LPCOLESTR CLSID_String, _In_ LPCOLESTR IID_String) {
- CLSID MyClsid;
- hr = CLSIDFromString(AddCurlyBracket(CLSID_String), &MyClsid);
- if (FAILED(hr))throw MyException("CLSIDFromString", -11);
- hr = CoCreateInstance(MyClsid, NULL, CLSCTX_INPROC_SERVER,
- IID_IUnknown, (LPVOID*)&pIUnknown);
- if (FAILED(hr))throw MyException("CoCreateInstance", -12);
- IID MyIID;
- hr = IIDFromString(AddCurlyBracket(IID_String), &MyIID);
- if (FAILED(hr))throw MyException("IIDFromString", -13);
- hr = pIUnknown->QueryInterface(MyIID, (void**)&pICreationInstance);
- if (FAILED(hr))throw MyException("QueryInterface", -14);
- if (pIUnknown + 1 != pICreationInstance) {
- ErrorMessage("pIUnknown + 1 ");
- }
- BSTR Description = ::SysAllocStringByteLen("", 5000);
- if (!Description)throw MyException("SysAllocStringLen", -15);
- hr = pICreationInstance->GetDescription(Description);
- if (FAILED(hr)) {
- ::SysFreeString(Description);
- throw MyException("GetDescription", -16);
- }
- // printf("%d", (*(INT32*)Description));
- MyWriteLine(L"%s", Description + 2);
- ::SysFreeString(Description);
- hr = pICreationInstance->GetDescription2(&Description);
- if (FAILED(hr)) throw MyException("GetDescription2", -17);
- MyWriteLine(L"%s", Description);
- ::SysFreeString(Description);
- }
- void My_Test_Function() {
- int length = ARRAYSIZE(ClientInfo);
- for (int aa = 0; aa < length; aa++) {
- HMODULE& hModule = *phModule_Chen++;
- const WCHAR* DLL_Absolute_Path = ToFullPath(MyPathRoot, ClientInfo[aa].DLL_Path);
- hModule = ClientInfo[aa].MFC_DLL ?
- AfxLoadLibrary(DLL_Absolute_Path) : LoadLibraryW(DLL_Absolute_Path);
- if (!hModule)throw MyException("LoadLibraryW", -21);
- using Test_UnregisteredServer = int (*)(TestParameter*);
- Test_UnregisteredServer FunctionPointer =
- (Test_UnregisteredServer)GetProcAddress(hModule, ClientInfo[aa].ProcName);
- if (!FunctionPointer) {
- if (b_FreeLibrary) {
- ClientInfo[aa].MFC_DLL ?
- AfxFreeLibrary(hModule) : FreeLibrary(hModule);
- --phModule_Chen;
- }
- throw MyException("GetProcAddress", -22);
- }
- TestParameter MyParameter = {
- Debug_namespace::My_Write_Line,
- pICreationInstance ,
- MyPathRoot
- };
- int rv = FunctionPointer(&MyParameter);
- if (b_FreeLibrary) {
- ClientInfo[aa].MFC_DLL ?
- AfxFreeLibrary(hModule) : FreeLibrary(hModule);
- --phModule_Chen;
- }
- if (rv < 0)throw MyException("Test unregistered server Function", rv);
- }
- }
- void ReleaseResource() {
- IDispatch* pIDispatch;
- hr = pIUnknown->QueryInterface(IID_IDispatch, (void**)&pIDispatch);
- if (FAILED(hr))
- ErrorMessage("QueryInterface (IID_IDispatch ");
- else
- printf(" %p(%d)pIDispatch\n", pIDispatch, pIDispatch->Release());
- printf(" %p(%d)pIUnknown\n", pIUnknown, pIUnknown->Release());
- printf(" %p(%d)pICreationInstance\n", pICreationInstance,
- pICreationInstance->Release());
- }
- void ErrorMessage(const CHAR* ERR_MSG) {
- MessageBeep(MB_ICONERROR);
- HANDLE herr = GetStdHandle(STD_ERROR_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO Screen_Buf;
- GetConsoleScreenBufferInfo(herr, &Screen_Buf);
- SetConsoleTextAttribute(herr, FOREGROUND_RED);
- fprintf(stderr, "%s\n", ERR_MSG);
- SetConsoleTextAttribute(herr, FOREGROUND_GREEN);
- int NoOpenStream = _flushall();//printf("No=%d\n", NoOpenStream);
- system("pause");
- SetConsoleTextAttribute(herr, Screen_Buf.wAttributes);
- }
- #define MyDebugFilename "MyFileForDebug.txt"
- #define _WMyDebugFilename OLESTR("MyFileForDebug.txt")
- Debug_namespace::FileForDebug::FileForDebug() :
- IsSave(false),
- OnDebug(false),
- TooLarge(false),
- previousCHAR{}, WriteSize(0), ReadSize(0),
- pStart_Previous(previousCHAR)
- {
- FILE* _Stream = NULL;
- errno_t errNo = _wfopen_s(&_Stream, ToFullPath(APP_Dir, _WMyDebugFilename), L"r,ccs=UNICODE");
- if (!_Stream || errNo) {
- ErrorMessage("Unable to open " MyDebugFilename);
- return;
- }
- ReadSize = fread_s(previousCHAR, sizeof(previousCHAR),
- sizeof(previousCHAR[0]), BufferSize_File, _Stream);
- fclose(_Stream);
- OnDebug = true;
- printf("BufferSize_File=%lluMB ReadFileSize=%llu\n", (BufferSize_File >> 20), ReadSize);
- system("pause");
- }
- void Debug_namespace::FileForDebug::Save() {
- if (IsSave || OnDebug) return;
- FILE* _Stream = NULL;
- errno_t errNo = _wfopen_s(&_Stream, ToFullPath(APP_Dir, _WMyDebugFilename), L"w,ccs=UNICODE");
- if (_Stream && !errNo) {
- WriteSize = fwrite(previousCHAR, sizeof(previousCHAR[0]),
- pStart_Previous - previousCHAR, _Stream);
- fclose(_Stream);
- IsSave = true;
- printf("BufferSize_File=%I64u ReadFileSize= %I64u\n", BufferSize_File, ReadSize);
- printf("BufferSize_File=%I64u WriteFileSize=%I64u\n", BufferSize_File, WriteSize);
- system("pause");
- }
- }
- void Debug_namespace::FileForDebug::compareData(const wchar_t* pStart, int size) {
- if (TooLarge)return;
- if (pStart_Previous + size > previousCHAR + BufferSize_File) {
- TooLarge = true;
- ErrorMessage("Output data Too Large in compareData");
- return;
- }
- if (OnDebug) {
- int ret = memcmp(pStart, pStart_Previous, sizeof(wchar_t) * size);
- if (ret) {
- OnDebug = false;
- ErrorMessage("The output is not consistent with previous one");
- }
- else { pStart_Previous += size; return; }
- }
- if (memcpy_s(pStart_Previous, size * sizeof(wchar_t),
- pStart, size * sizeof(wchar_t))) {
- ErrorMessage("memcpy_s");
- }
- pStart_Previous += size;
- }
- };
- #endif
- #pragma once
- #include "PathCch.h"
- __interface ICreationInstance :IDispatch
- {
- HRESULT Get_Interface3(
- _In_ PVOID AssemblyInfo_ptr,
- _COM_Outptr_ PVOID* ppvid);
- HRESULT GetDescription(
- _In_ BSTR description);
- HRESULT GetDescription2(
- _Out_ BSTR* description);
- };
- typedef void (*MyWriteLine)(const WCHAR* format, va_list);
- struct TestParameter {
- MyWriteLine MyWriteLine;
- PVOID ptr_to_Interface;
- const WCHAR* PathRoot;
- };
- const WCHAR* AddCurlyBracket(const WCHAR* uuid) {
- const size_t MAX_index = 5, Max_length = 40;
- static WCHAR TempUUID[MAX_index][Max_length + 3];
- static size_t index = 0;
- if (++index >= MAX_index)index = 0;
- WCHAR* const UUID_ = TempUUID[index];
- size_t size_uuid = wcsnlen_s(uuid, Max_length);
- wcsncpy_s(UUID_ + 1, Max_length, uuid, size_uuid);
- UUID_[0] = L'{'; // '\u007b';
- UUID_[size_uuid + 1] = L'}'; //'\u007d';
- UUID_[size_uuid + 2] = L'\u0000'; // '\0';
- //wprintf(L"%s\n", UUID_);system("pause");
- return TempUUID[index];
- }
- const WCHAR* ToFullPath(const WCHAR* pRoot, const WCHAR* relativePath) {
- const size_t MAX_index = 5, Max_length = 4000;
- static WCHAR tempFullPath[MAX_index][Max_length];
- static size_t index = 0;
- if (++index >= MAX_index)index = 0;
- wcscpy_s<Max_length>(tempFullPath[index], pRoot);
- PathCchAppend(tempFullPath[index], Max_length, relativePath);
- return tempFullPath[index];
- }
- class ExportedData {
- MyWriteLine MyWriteLine;
- const WCHAR* start;
- va_list My_va_list;
- static inline ExportedData* ED_ptr = nullptr;
- public:
- static inline ExportedData* const MySelf() { return ED_ptr; }
- void WriteLine(const WCHAR* format, ...) {
- va_start(My_va_list, format);
- MyWriteLine(format, My_va_list);
- va_end(My_va_list);
- }
- ExportedData(TestParameter* pTestParameter, const WCHAR* start) {
- MyWriteLine = pTestParameter->MyWriteLine;
- this->start = start;
- ED_ptr = this;
- WriteLine(L"====== Begin %s =======", start);
- }
- ~ExportedData() {
- WriteLine(L"====== End %s =======", start);
- ED_ptr = nullptr;
- //system("pause");
- }
- };

- #If TARGET = "library" And PLATFORM = "x64" Then
- Option Strict On
- Imports System.Reflection
- Imports System.Runtime.InteropServices
- Imports System.Text
- <ComClass(
- "91DD12FD-4DBD-4B83-AC40-439E3B6393A1",
- "85927839-0BB2-423B-97D6-89A2D4002519"
- )>
- Public Class RegisteredLib
- Sub Get_Interface3(<[In]> AssemblyInfo_ptr As IntPtr,
- <Out> ByRef ppVoid As IntPtr)
- Try
- MyAssemblyInfo =
- Marshal.PtrToStructure(Of AssemblyInfo_Struct)(AssemblyInfo_ptr)
- AssemblyPath =
- Marshal.PtrToStringBSTR(MyAssemblyInfo.AssemblyPath)
- UnregisteredServerAssembly = Assembly.LoadFrom(AssemblyPath)
- InvokeCreationMethod()
- ppVoid = Marshal.ReadIntPtr(ppvoid_temp)
- Catch ex As IO.FileNotFoundException
- MsgBox("Not found " & AssemblyPath & "--Chen")
- Throw New MyException(&HE0000001, "FileNotFoundException")
- Catch ex As Exception
- Throw New MyException(&HE0000111,
- $"Unknown Exception--{ex.Message}")
- End Try
- End Sub
- Sub GetDescription(Description As IntPtr)
- Dim Source As New StringBuilder(
- "This is a CreationInstance for getting unregistered servers")
- Source.AppendLine()
- Source.AppendLine("HRESULT value reference : winerror.h")
- Source.AppendLine(
- "My location is " &
- System.Reflection.Assembly.GetExecutingAssembly.Location)
- Source.AppendLine(
- "FrameworkDescription is " &
- System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription
- )
- Dim MainType As Type = GetType(RegisteredLib)
- Dim ThisModule As Reflection.Module = MainType.Module
- Dim peKind As PortableExecutableKinds
- Dim machine As ImageFileMachine
- ThisModule.GetPEKind(peKind, machine)
- Source.AppendFormat("machine={0:G} peKind={1:G}", machine, peKind)
- Source.Append(ChrW(0))
- Dim BufferSize As Int32 = Marshal.ReadInt32(Description - 4)
- If BufferSize < (4 + Source.Length * 2) Then
- Marshal.WriteInt32(Description, 0)
- End If
- Marshal.Copy(Source.ToString().ToCharArray(), 0,
- Description + 4, Source.Length)
- Marshal.WriteInt32(Description, (Source.Length - 1) * 2)
- End Sub
- Sub GetDescription2(<Out> ByRef Description As String)
- Dim MainType As Type = GetType(RegisteredLib)
- Dim ThisModule As Reflection.Module = MainType.Module
- Dim peKind As PortableExecutableKinds
- Dim machine As ImageFileMachine
- ThisModule.GetPEKind(peKind, machine)
- Dim Source As New StringBuilder(
- "This is a CreationInstance for getting unregistered servers" &
- vbNewLine & "HRESULT value reference : winerror.h" &
- vbNewLine & "My location is " &
- System.Reflection.Assembly.GetExecutingAssembly.Location &
- vbNewLine & "FrameworkDescription is " &
- System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription &
- vbNewLine & $"machine={machine} peKind={peKind}"
- )
- Description = Source.ToString()
- End Sub
- '============================================================
- Public Sub New()
- MyBase.New()
- ppvoid_temp = Marshal.AllocCoTaskMem(12)
- End Sub
- Protected Sub Finallize()
- Marshal.FreeCoTaskMem(ppvoid_temp)
- End Sub
- Private Class MyException
- Inherits Exception
- Sub New(errorcode As Int32, Message As String)
- MyBase.New(Message)
- HResult = errorcode
- End Sub
- End Class
- Dim MyAssemblyInfo As AssemblyInfo_Struct
- Structure AssemblyInfo_Struct
- Public AssemblyPath As IntPtr
- Public TypeFullname As IntPtr
- Public CreationMethod As IntPtr
- Public CLSID As IntPtr
- Public IID As IntPtr
- End Structure
- Dim AssemblyPath As String
- Dim TypeFullname As String
- Dim CreationMethod As String
- Dim CLSID_string As String
- Dim IID_string As String
- ReadOnly ppvoid_temp As IntPtr
- Dim UnregisteredServerAssembly As Assembly
- Dim IEnumateType As IEnumerable(Of Type)
- Private Sub InvokeCreationMethod()
- Dim Type_CLSID As Guid
- CLSID_string =
- Marshal.PtrToStringBSTR(MyAssemblyInfo.CLSID)
- If Not Guid.TryParse(CLSID_string, Type_CLSID) Then
- Throw New Exception($"Error:CLSID({CLSID_string})")
- End If
- IEnumateType = UnregisteredServerAssembly.ExportedTypes
- For Each MyType As TypeInfo In IEnumateType
- If Type_CLSID <> MyType.GUID Then Continue For
- TypeFullname = Marshal.PtrToStringBSTR(
- MyAssemblyInfo.TypeFullname)
- If TypeFullname <> MyType.FullName Then
- MsgBox(TypeFullname & vbNewLine &
- MyType.FullName)
- End If
- Dim UnregisteredServerType As Type = MyType.AsType
- CreationMethod =
- Marshal.PtrToStringBSTR(MyAssemblyInfo.CreationMethod)
- Dim CreateObject_Chen As MethodInfo =
- UnregisteredServerType.GetMethod(CreationMethod)
- If CreateObject_Chen Is Nothing Then
- Throw New Exception($"Error:CreateMethod({CreationMethod})")
- End If
- IID_string = Marshal.PtrToStringBSTR(MyAssemblyInfo.IID)
- Dim Interface_IID As Guid
- If Not Guid.TryParse(IID_string, Interface_IID) Then
- Throw New Exception($"Error:Interface_IID({IID_string})")
- End If
- Dim obj() As Object = {Interface_IID, ppvoid_temp, New IntPtr(12345)}
- CreateObject_Chen.Invoke(Nothing, obj)
- Exit Sub
- Next
- Throw New Exception("Error:Nothing")
- End Sub
- End Class
- #End If
- // MFC_DLL_Test_Marshalling.cpp : Defines the exported functions for the DLL.
- //
- #include "framework.h"
- #include "MFC_DLL_Test_Marshalling.h"
- #include <stdio.h>
- #include <Combaseapi.h>
- #include "oleauto.h"
- #include "propvarutil.h"
- #include <typeinfo>
- #include <type_traits>
- #include <concepts>
- #include "TestParameter.h"
- // This is an example of an exported variable
- MFCDLLTESTMARSHALLING_API int nMFCDLLTestMarshalling=0;
- // This is an example of an exported function.
- MFCDLLTESTMARSHALLING_API int fnMFCDLLTestMarshalling(void)
- {
- return 0;
- }
- // This is the constructor of a class that has been exported.
- CMFCDLLTestMarshalling::CMFCDLLTestMarshalling()
- {
- return;
- }
- #if defined(_M_AMD64) && defined(_WIN64) && defined(_WINDOWS) && \
- defined(_USRDLL) && _MSVC_LANG >= 202002L
- extern "C" /* exported functions */ {
- int MFC_DLL_Test_UnregisteredServer1(TestParameter*);
- int MFC_DLL_Test_UnregisteredServer2(TestParameter*);
- int MFC_DLL_Test_IXXXX(TestParameter*);
- }
- IUnknown* pIUnknown;
- HRESULT hr;
- template <class T> concept Is_BSTR_v = std::is_convertible_v<T, BSTR>;
- template <class T> concept Is_LPCOLESTR_v = std::is_convertible_v<LPCOLESTR, T>;
- template <typename T>
- struct ServerInfo_Struct {
- T AssemblyPath;
- T TypeFullName;
- T CreationMethod;
- T CLSID;
- T IID;
- ServerInfo_Struct(T t1, T t2, T t3, T t4, T t5) :
- AssemblyPath(t1),
- TypeFullName(t2),
- CreationMethod(t3),
- CLSID(t4),
- IID(t5) {
- }
- ServerInfo_Struct& operator=(ServerInfo_Struct&) = delete;
- ServerInfo_Struct(const ServerInfo_Struct&) = delete;
- ~ServerInfo_Struct() requires Is_BSTR_v<T> {
- if (0 == strcmp(typeid(T).name(), typeid(BSTR).name())) {
- printf("std::is_convertible_v< %s , %s >\n",
- typeid(T).name(), typeid(BSTR).name());
- }
- else printf("===> Error:%s\n", typeid(T).name());
- ::SysFreeString((wchar_t*)AssemblyPath);
- ::SysFreeString((wchar_t*)TypeFullName);
- ::SysFreeString((wchar_t*)CreationMethod);
- ::SysFreeString((wchar_t*)CLSID);
- ::SysFreeString((wchar_t*)IID);
- }
- ~ServerInfo_Struct()requires Is_LPCOLESTR_v<T> {
- puts(typeid(T).name());
- if (0 == strcmp(typeid(LPCOLESTR).name(), typeid(T).name())) {
- printf("std::is_convertible_v< %s , %s >\n",
- typeid(LPCOLESTR).name(), typeid(T).name());
- }
- else printf("===> Error:%s\n", typeid(T).name());
- }
- };
- template ServerInfo_Struct<LPCOLESTR>;
- template ServerInfo_Struct<BSTR>;
- #ifdef _DEBUG
- const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
- "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Debug\\NotRegisteredServer.dll"
- );
- #else
- const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
- "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Release\\NotRegisteredServer.dll"
- );
- #endif
- ServerInfo_Struct<LPCOLESTR> My_Server_string[] = {
- {
- MyServerName,
- (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer1"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("04D9F530-CE0C-4232-8F3F-6E0A3244C715"),
- (LPCOLESTR)OLESTR("31D53FF8-4768-4A77-95E3-DC28DEBB375F")
- },{
- MyServerName,
- (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
- (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
- },{
- MyServerName,
- (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
- (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
- }
- };
- int Get_ServerInterface(TestParameter* ptr, int interfaceID, PVOID* pRetVal) {
- ICreationInstance* pICreationInstance =
- (ICreationInstance*)ptr->ptr_to_Interface;
- ServerInfo_Struct<LPCOLESTR>& MyServerString = My_Server_string[interfaceID];
- ServerInfo_Struct<BSTR> My_Server{
- SysAllocString(ToFullPath(ptr->PathRoot,MyServerString.AssemblyPath)),
- SysAllocString(MyServerString.TypeFullName),
- SysAllocString(MyServerString.CreationMethod),
- SysAllocString(MyServerString.CLSID),
- SysAllocString(MyServerString.IID)
- };
- hr = pICreationInstance->Get_Interface3(&My_Server, (PVOID*)&pIUnknown);
- if (FAILED(hr))return -31;
- IID myiid;
- hr = IIDFromString(AddCurlyBracket(My_Server.IID), &myiid);
- if (FAILED(hr))return -32;
- hr = pIUnknown->QueryInterface(myiid, pRetVal);
- if (FAILED(hr))return -33;
- return 0;
- }
- /* Begin MFC_DLL_Test_UnregisteredServer1 */
- void This_Delegate_will_be_called_While_RaiseEvent(VARIANTARG VAR) {
- ExportedData::MySelf()->WriteLine(L"This_Delegate_will_be_called_While_RaiseEvent(VT_BSTR=%d V_VT(&VAR)=%d)",
- VT_BSTR, V_VT(&VAR));
- ExportedData::MySelf()->WriteLine(L"<-- %s -->", V_BSTR(&VAR));
- }
- __interface IUnregisteredServer1 :IDispatch
- {
- HRESULT Get_Interface(PVOID*);
- HRESULT Get_Interface2(long, VARIANTARG*);
- HRESULT Register_Event(void (*)(VARIANT), BSTR, INT32* ID);
- HRESULT RemoveEvent(INT32 ID);
- HRESULT Raise_Event(LONG64);
- HRESULT Get_MyProperty(INT32*);
- HRESULT Put_MyProperty(INT32 pRetVal);
- HRESULT GetTraceMessage(BSTR*);
- };
- int MFC_DLL_Test_UnregisteredServer1(TestParameter* ptr) {
- ExportedData ED(ptr, L"MFC_DLL_Test_UnregisteredServer1");
- IUnregisteredServer1* pIUnregisteredServer1;
- int rv = Get_ServerInterface(ptr, 0, (PVOID*)&pIUnregisteredServer1);
- if (rv < 0)return rv;
- INT32 _INT32 = 777;
- ED.WriteLine(L"(%d)", _INT32);
- pIUnregisteredServer1->Get_MyProperty(&_INT32);
- ED.WriteLine(L"(%d)", _INT32);
- INT32 EventID[3]{};
- BSTR MyString_BSTR = SysAllocString(L"Register_Event(&This_Delegate_will_be_called_While_RaiseEvent, MyString_BSTR)");
- for (INT64 aa = 21; aa < 25; aa++) {
- for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
- pIUnregisteredServer1->Register_Event(&This_Delegate_will_be_called_While_RaiseEvent,
- MyString_BSTR, &EventID[bb]);
- }
- pIUnregisteredServer1->Raise_Event(aa);
- for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
- pIUnregisteredServer1->RemoveEvent(EventID[bb]);
- }
- }
- ::SysFreeString(MyString_BSTR);
- IUnknown* _ptr2_;
- pIUnregisteredServer1->Get_Interface((PVOID*)&_ptr2_);
- if (pIUnknown != _ptr2_) {
- ED.WriteLine(L"Error1:%p", pIUnknown);
- ED.WriteLine(L"Error1:%p", _ptr2_);
- }
- VARIANT _variant;
- VariantInit(&_variant);
- pIUnregisteredServer1->Get_Interface2(2, &_variant);
- if (V_VT(&_variant) != VT_UNKNOWN) {
- ED.WriteLine(L"error: V_VT(&_variant)=%d", V_VT(&_variant));
- }
- _ptr2_ = V_DISPATCH(&_variant);
- if (pIUnknown != _ptr2_) {
- ED.WriteLine(L"Error2:%p", pIUnknown);
- ED.WriteLine(L"Error2:%p", _ptr2_);
- }
- BSTR MyMessage = NULL;
- pIUnregisteredServer1->GetTraceMessage(&MyMessage);
- ED.WriteLine(L"GetTraceMessage");
- ED.WriteLine(L"%s", MyMessage);
- SysFreeString(MyMessage);
- return 0;
- }
- /* End MFC_DLL_Test_UnregisteredServer1 */
- // 1 ======================================================= 2
- /* Begin MFC_DLL_Test_UnregisteredServer2 */
- __interface IUnregisteredServer2_CPP :public IDispatch
- {
- public:
- HRESULT DefaultMarshallingForObject(VARIANT* v, VARIANT* v2, VARIANT* v3);
- HRESULT Map_HResultAndException(BSTR* display);
- HRESULT Hello_world3(
- DECIMAL decimal2,
- GUID guid2,
- BSTR* outputResult
- );
- virtual HRESULT STDMETHODCALLTYPE QueryInterface2(
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void** ppvObject) = 0;
- virtual ULONG STDMETHODCALLTYPE AddRef2(void) = 0;
- virtual ULONG STDMETHODCALLTYPE Release2(void) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount2(
- /* [out] */ __RPC__out UINT* pctinfo) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetTypeInfo2(
- /* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames2(
- /* [in] */ __RPC__in REFIID riid,
- /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
- /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId) = 0;
- virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke2(
- /* [annotation][in] */
- _In_ DISPID dispIdMember,
- /* [annotation][in] */
- _In_ REFIID riid,
- /* [annotation][in] */
- _In_ LCID lcid,
- /* [annotation][in] */
- _In_ WORD wFlags,
- /* [annotation][out][in] */
- _In_ DISPPARAMS* pDispParams,
- /* [annotation][out] */
- _Out_opt_ VARIANT* pVarResult,
- /* [annotation][out] */
- _Out_opt_ EXCEPINFO* pExcepInfo,
- /* [annotation][out] */
- _Out_opt_ UINT* puArgErr) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetTraceMessage(BSTR*) = 0;
- };
- extern "C" {
- /* [unique][uuid][object] */
- typedef interface IUnregisteredServer2_C IUnregisteredServer2_C;
- typedef struct IUnregisteredServer2_CVtbl
- {
- BEGIN_INTERFACE
- HRESULT(STDMETHODCALLTYPE* QueryInterface)(
- __RPC__in IDispatch* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void** ppvObject);
- ULONG(STDMETHODCALLTYPE* AddRef)(
- __RPC__in IUnregisteredServer2_C* This);
- ULONG(STDMETHODCALLTYPE* Release)(
- __RPC__in IUnregisteredServer2_C* This);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [out] */ __RPC__out UINT* pctinfo);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfo)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);
- HRESULT(STDMETHODCALLTYPE* GetIDsOfNames)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
- /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke)(
- IUnregisteredServer2_C* This,
- /* [annotation][in] */
- _In_ DISPID dispIdMember,
- /* [annotation][in] */
- _In_ REFIID riid,
- /* [annotation][in] */
- _In_ LCID lcid,
- /* [annotation][in] */
- _In_ WORD wFlags,
- /* [annotation][out][in] */
- _In_ DISPPARAMS* pDispParams,
- /* [annotation][out] */
- _Out_opt_ VARIANT* pVarResult,
- /* [annotation][out] */
- _Out_opt_ EXCEPINFO* pExcepInfo,
- /* [annotation][out] */
- _Out_opt_ UINT* puArgErr);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* DefaultMarshallingForObject)(
- __RPC__in IUnregisteredServer2_C* This,
- VARIANT* v,
- VARIANT* v2,
- VARIANT* v3
- );
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Map_HResultAndException)(
- __RPC__in IUnregisteredServer2_C* This, BSTR* Display
- );
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Hello_world3)(
- __RPC__in IUnregisteredServer2_C* This,
- DECIMAL decimal2,
- GUID guid2,
- BSTR* outputResult
- );
- HRESULT(STDMETHODCALLTYPE* QueryInterface2)(
- __RPC__in IDispatch* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void** ppvObject);
- ULONG(STDMETHODCALLTYPE* AddRef2)(
- __RPC__in IUnregisteredServer2_C* This);
- ULONG(STDMETHODCALLTYPE* Release2)(
- __RPC__in IUnregisteredServer2_C* This);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount2)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [out] */ __RPC__out UINT* pctinfo);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfo2)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);
- HRESULT(STDMETHODCALLTYPE* GetIDsOfNames2)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
- /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke2)(
- IUnregisteredServer2_C* This,
- /* [annotation][in] */
- _In_ DISPID dispIdMember,
- /* [annotation][in] */
- _In_ REFIID riid,
- /* [annotation][in] */
- _In_ LCID lcid,
- /* [annotation][in] */
- _In_ WORD wFlags,
- /* [annotation][out][in] */
- _In_ DISPPARAMS* pDispParams,
- /* [annotation][out] */
- _Out_opt_ VARIANT* pVarResult,
- /* [annotation][out] */
- _Out_opt_ EXCEPINFO* pExcepInfo,
- /* [annotation][out] */
- _Out_opt_ UINT* puArgErr);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* GetTraceMessage)(
- __RPC__in IUnregisteredServer2_C* This, BSTR*
- );
- END_INTERFACE
- } IUnregisteredServer2_CVtbl;
- interface IUnregisteredServer2_C
- {
- CONST_VTBL struct IUnregisteredServer2_CVtbl* lpVtbl;
- };
- #define IUnregisteredServer2_C_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
- #define IUnregisteredServer2_C_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
- #define IUnregisteredServer2_C_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
- #define IUnregisteredServer2_C_GetTypeInfoCount(This,pctinfo) \
- ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
- #define IUnregisteredServer2_C_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
- ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
- #define IUnregisteredServer2_C_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
- ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
- #define IUnregisteredServer2_C_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
- ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
- #define IUnregisteredServer2_C_DefaultMarshallingForObject(This,variant,v2,v3) \
- ( (This)->lpVtbl -> DefaultMarshallingForObject(This,variant,v2,v3) )
- }
- int MFC_DLL_Test_UnregisteredServer2(TestParameter* ptr) {
- ExportedData ED(ptr, L"MFC_DLL_Test_UnregisteredServer2");
- IUnregisteredServer2_CPP* pIUnregisteredServer2_CPP;
- int rv = Get_ServerInterface(ptr, 1, (PVOID*)&pIUnregisteredServer2_CPP);
- if (rv < 0)return rv;
- VARIANT v, v2, v3;
- VariantInit(&v); VariantInit(&v2); VariantInit(&v3);
- InitVariantFromInt32(0x12345, &v);
- ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
- pIUnregisteredServer2_CPP->DefaultMarshallingForObject(&v, &v2, &v3);
- if (V_VT(&v) != VT_I8) return -3005;
- ED.WriteLine(L"V_VT(&v)=%d %X ", V_VT(&v), V_I8(&v));
- ED.WriteLine(L"V_VT(&v2)=%d %f ", V_VT(&v2), V_R8(&v2));
- DECIMAL decimal{ };
- decimal.Lo32 = 6666666; decimal.scale = 3;
- GUID guid;
- hr = CLSIDFromString(OLESTR("{45A82A95-6446-43F0-83B9-71E7469E14D2}"),
- &guid);
- if (FAILED(hr)) return -3008;
- BSTR outputResult = NULL;
- pIUnregisteredServer2_CPP->Hello_world3(decimal, guid,
- &outputResult);
- ED.WriteLine(L"outputResult %s", outputResult);
- ::SysFreeString(outputResult);
- IUnregisteredServer2_C* pIUnregisteredServer2_C =
- (IUnregisteredServer2_C*)pIUnregisteredServer2_CPP;
- if ((void*)pIUnregisteredServer2_CPP != (void*)pIUnregisteredServer2_C) {
- ED.WriteLine(L"pIUnregisteredServer2_CPP=%p", pIUnregisteredServer2_CPP);
- ED.WriteLine(L"pIUnregisteredServer2_C =%p", pIUnregisteredServer2_C);
- }
- VariantInit(&v);
- VariantInit(&v2);
- VariantInit(&v3);
- InitVariantFromInt32(321, &v);
- for (int aa = 0; aa < 1; aa++) {
- IUnregisteredServer2_C_DefaultMarshallingForObject(
- pIUnregisteredServer2_C, &v, &v2, &v3);
- ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
- }
- BSTR Display = NULL;
- hr = pIUnregisteredServer2_C->lpVtbl->Map_HResultAndException(
- pIUnregisteredServer2_C, &Display);
- ED.WriteLine(L"hr=0X%X", hr);
- ED.WriteLine(L"Display=%s", Display);
- if (Display) ::SysFreeString(Display);
- ED.WriteLine(L"sizeof(lpVtbl)=%d", sizeof(pIUnregisteredServer2_C->lpVtbl));
- BSTR MyMessage = NULL;
- pIUnregisteredServer2_C->lpVtbl->GetTraceMessage(
- pIUnregisteredServer2_C, &MyMessage);
- ED.WriteLine(L"GetTraceMessage");
- ED.WriteLine(L"%s", MyMessage);
- SysFreeString(MyMessage);
- return 0;
- }
- /* End MFC_DLL_Test_UnregisteredServer2 */
- // 2 ================================================= 3
- /* Begin MFC_DLL_Test_IXXXX */
- __interface IXXXX :public IUnregisteredServer2_CPP
- {
- HRESULT YYYY(INT64*);
- HRESULT YYYY1(BSTR*);
- };
- int MFC_DLL_Test_IXXXX(TestParameter* ptr) {
- ExportedData ED(ptr, L"MFC_DLL_Test_IXXXX");
- IXXXX* pIXXXX;
- int rv = Get_ServerInterface(ptr, 2, (PVOID*)&pIXXXX);
- if (rv < 0)return rv;
- INT64 aaa;
- pIXXXX->YYYY(&aaa);
- ED.WriteLine(L"aaa = %d", aaa);
- BSTR comment = ::SysAllocString(L" ABC ");
- pIXXXX->YYYY1(&comment);
- ED.WriteLine(L"comment=%s", comment);
- ::SysFreeString(comment);
- BSTR Trace = NULL;
- pIXXXX->GetTraceMessage(&Trace);
- ED.WriteLine(L"%s", Trace);
- ::SysFreeString(Trace);
- return 0;
- }
- /* End MFC_DLL_Test_IXXXX */
- #endif // _DLL
- LIBRARY
- EXPORTS
- MFC_DLL_Test_UnregisteredServer1 @1
- MFC_DLL_Test_UnregisteredServer2 @2
- MFC_DLL_Test_IXXXX @3
- #If TARGET = "library" And PLATFORM = "x64" Then
- Option Strict On
- Imports System.Runtime.InteropServices
- <Guid("31D53FF8-4768-4A77-95E3-DC28DEBB375F")>
- Public Interface IUnregisterServer1
- ReadOnly Property Get_Interface() As <MarshalAs(UnmanagedType.IDispatch)> Object
- Sub Get_Interface2(Interface_ID As Int32, <Out> ByRef ppVoid As Object)
- Sub Register_Event(<[In]()> FunctionPointer As IntPtr,
- <[In], MarshalAs(UnmanagedType.BStr)> BSTR_String As String,
- <Out> ByRef ID As Int32)
- Sub RemoveEvent(<[In]> ID As Int32)
- Sub Raise_Event(long64 As Int64)
- Property MyProperty As Int32
- ReadOnly Property TraceMessage As String
- End Interface
- <ComClass(
- "04D9F530-CE0C-4232-8F3F-6E0A3244C715",
- "31D53FF8-4768-4A77-95E3-DC28DEBB375F",
- "89E4014F-3A6D-44E6-A9D3-E1CA6655B572"
- )>
- Public Class MyUnregisterServer1 : Implements IUnregisterServer1
- ReadOnly Property Get_Interface() As <MarshalAs(UnmanagedType.IUnknown)> Object _
- Implements IUnregisterServer1.Get_Interface
- Get
- MyTrace("Get_Interface")
- Return CreateObject_Chen()
- End Get
- End Property
- Sub Get_Interface2(Interface_ID As Int32, <Out> ByRef ppVoid As Object) _
- Implements IUnregisterServer1.Get_Interface2
- MyTrace("Get_Interface2")
- ppVoid = CreateObject_Chen()
- End Sub
- Sub Register_Event(
- <[In]> FunctionPointer As IntPtr,
- <[In], MarshalAs(UnmanagedType.BStr)> BSTR_String As String,
- <Out> ByRef ID As Int32) _
- Implements IUnregisterServer1.Register_Event
- CppEventClassObj.Register_Event(FunctionPointer, BSTR_String, ID)
- MyTrace($"Register_Event {ID}")
- End Sub
- Sub RemoveEvent(<[In]> ID As Int32) _
- Implements IUnregisterServer1.RemoveEvent
- MyTrace($"RemoveEvent {ID}")
- CppEventClassObj.RemoveEvent(ID)
- End Sub
- Sub Raise_Event(MyTestParameter As Int64) Implements IUnregisterServer1.Raise_Event
- MyTrace($"Raise_Event {MyTestParameter}")
- CppEventClassObj.RaiseEventParameter = MyTestParameter
- RaiseEvent Cpp_Event(Me, CppEventClassObj)
- End Sub
- Dim _MyProperty As Int32 = 222
- Public Property MyProperty As Int32 Implements IUnregisterServer1.MyProperty
- Get
- MyTrace($"Get MyProperty {_MyProperty + 111}")
- Return _MyProperty + 111
- End Get
- Set(value As Int32)
- MyTrace($"Set MyProperty value= {value}")
- _MyProperty = value
- End Set
- End Property
- Public ReadOnly Property TraceMessage As String Implements IUnregisterServer1.TraceMessage
- Get
- TraceMessage = vbNewLine &
- "==== TraceMessage(Chen Inn-Jer) ======" &
- vbNewLine & _TraceMessage.ToString() &
- "==== TraceMessage(Chen Inn-Jer) ======" &
- vbNewLine
- _TraceMessage.Clear() : TraceSteps = 0
- End Get
- End Property
- '1----------------------------------------------------
- Private TraceSteps As Int32
- Private ReadOnly _TraceMessage As Text.StringBuilder
- Shared MyUnregisterServer1_Object As MyUnregisterServer1
- Shared Function CreateObject_Chen() As IUnregisterServer1
- If MyUnregisterServer1_Object Is Nothing Then
- MyUnregisterServer1_Object = New MyUnregisterServer1
- End If
- Return CType(MyUnregisterServer1_Object, IUnregisterServer1)
- End Function
- Shared Sub CreateObject3_Chen(ByRef IID As Guid,
- ppvoid_temp As IntPtr, Not_Used As IntPtr)
- If MyUnregisterServer1_Object Is Nothing Then
- MyUnregisterServer1_Object = New MyUnregisterServer1
- End If
- MyUnregisterServer1_Object.MyTrace(
- $"MyUnregisterServer1 IID={IID} Not_Used = {Not_Used}")
- If IID = GetType(IUnregisterServer1).GUID Then
- Dim IUnregisteredInterface As IUnregisterServer1 =
- CType(MyUnregisterServer1_Object, IUnregisterServer1)
- Dim ppvoid As IntPtr =
- Marshal.GetIUnknownForObject(IUnregisteredInterface)
- Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
- Exit Sub
- End If
- MsgBox("Error:Nothing in CreateObject3_Chen")
- End Sub
- Sub New()
- MyBase.New()
- CppEventClassObj = New CppEventClass(Me)
- _TraceMessage = New Text.StringBuilder
- TraceSteps = 0
- End Sub
- Private Class CppEventClass : Inherits EventArgs
- Public RaiseEventParameter As Int64
- Private EventCount As Int32
- Delegate Sub DelegateForFunctionPointer(
- ByRef obj As System.Object)
- Structure RegisterEvent_Struct
- Dim FunctionPtr As IntPtr
- Dim InputString As String
- Dim ID As Int32
- End Structure
- Dim ObjectOwnCppEvent As MyUnregisterServer1
- ReadOnly RegisterEventList As List(Of RegisterEvent_Struct)
- Sub New(ObjectOwnCppEvent As MyUnregisterServer1)
- Me.ObjectOwnCppEvent = ObjectOwnCppEvent
- RegisterEventList = New List(Of RegisterEvent_Struct)
- End Sub
- Sub Register_Event(FunctionPointer As IntPtr,
- BSTR_String As String, ByRef ID As Int32)
- EventCount += 1
- ID = EventCount
- RegisterEventList.Add(New RegisterEvent_Struct With {
- .FunctionPtr = FunctionPointer,
- .InputString = BSTR_String,
- .ID = ID
- })
- If RegisterEventList.Count = 1 Then
- AddHandler ObjectOwnCppEvent.Cpp_Event,
- AddressOf Handler_For_Cpp_Event
- End If
- End Sub
- Sub RemoveEvent(ID As Int32)
- For Each myitem As RegisterEvent_Struct In RegisterEventList
- If myitem.ID = ID Then
- If RegisterEventList.Count = 1 Then
- RemoveHandler ObjectOwnCppEvent.Cpp_Event,
- AddressOf Handler_For_Cpp_Event
- End If
- RegisterEventList.Remove(myitem)
- Exit Sub
- End If
- Next
- Throw New MyException(&HA0010002, "Error:RemoveEvent")
- End Sub
- Sub Handler_For_Cpp_Event(sender As Object, e As EventArgs)
- For Each MyItem As RegisterEvent_Struct In RegisterEventList
- Dim DelegateForFunPtr As DelegateForFunctionPointer = CType(
- Marshal.GetDelegateForFunctionPointer(
- MyItem.FunctionPtr, GetType(DelegateForFunctionPointer)),
- DelegateForFunctionPointer)
- If DelegateForFunPtr Is Nothing Then
- MsgBox("DelegateForFunPtr Is Nothing")
- Else
- DelegateForFunPtr.Invoke(
- $"({RaiseEventParameter})" &
- "Sub Handler_For_Cpp_Event" &
- vbNewLine & MyItem.InputString)
- End If
- Next
- End Sub
- End Class
- Private ReadOnly CppEventClassObj As CppEventClass
- Public Event Cpp_Event As EventHandler
- Private Class MyException
- Inherits Exception
- Sub New(errorcode As Int32, Message As String)
- MyBase.New(Message)
- HResult = errorcode
- End Sub
- End Class
- Private Sub MyTrace(msg As String)
- TraceSteps += 1
- _TraceMessage.AppendLine($"{TraceSteps:d2} : {msg}")
- End Sub
- End Class
- '1 ================================================== 2
- <Guid("FDD5D79A-386E-49D0-AF60-81222A990055")>
- Public Interface IUnregisterServer2
- '<DispId(&H11)>
- Sub DefaultMarshallingForObject(
- ByRef obj As Object,
- ByRef obj2 As Object,
- ByRef obj3 As Object
- )
- Sub Map_HResultAndException(
- <Out, MarshalAs(UnmanagedType.BStr)>
- ByRef Display As String)
- Sub Hello_world3(decimal2 As System.Decimal,
- guid2 As System.Guid,
- <Out, MarshalAs(UnmanagedType.BStr)> ByRef OutputResulr As String
- )
- Sub QueryInterface2(
- <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
- <Out, MarshalAs(UnmanagedType.IUnknown)> ByRef ppVoid As Object)
- Sub AddRef2()
- Sub Release2()
- Sub GetTypeInfoCount2(
- <Out> ByRef out_UINT_pctinfo As UInt32)
- Sub GetTypeInfo2(
- <[In]()> itinfo As UInt32,
- <[In]()> lcid As UInt32,
- <Out, MarshalAs(UnmanagedType.Interface)> ByRef ppTInfo As Object)
- Sub GetIDsOfNames2(
- <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
- <[In](), MarshalAs(UnmanagedType.LPStr)> LPOLESTR_rgszNames As String,
- <[In]()> cNames As UInt32,
- <[In]()> LCID_lcid As UInt32,
- <Out> ByRef rgDispId As Int32)
- Sub Invoke2(
- <[In]()> _In_DISPID_dispIdMember As Int32,
- <[In](), MarshalAs(UnmanagedType.LPStruct)> _In_REFIIDriid As Guid,
- <[In]()> _In_LCID_lcid As UInt32,
- <[In]()> _In_WORD_wFlags As UInt16,
- <[In]()> _In_pDispParams As IntPtr,
- <Out> ByRef _Out_opt_VARIANT_pVarResult As Object,
- <Out> ByRef _Out_opt_pExcepInfo As IntPtr,
- <Out> ByRef _Out_opt_puArgErr As UInt32)
- ReadOnly Property TraceMessage As String
- End Interface
- <Guid("FDD5D79A-386E-49D0-AF60-81222A990055")>
- Public Interface IXXXX
- Sub YYYY(<Out> ByRef ppvoid As IntPtr)
- Sub YYYY1(<[In], Out, MarshalAs(UnmanagedType.BStr)> ByRef Comment As String)
- End Interface
- <ComClass("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D",
- "FDD5D79A-386E-49D0-AF60-81222A990055"
- )>
- Public Class MyUnregisterServer2
- Implements IUnregisterServer2, IXXXX
- Public Sub DefaultMarshallingForObject(
- ByRef obj As Object,
- ByRef obj2 As Object,
- ByRef obj3 As Object
- ) Implements IUnregisterServer2.DefaultMarshallingForObject
- MyTrace($"({obj})DefaultMarshallingForObject-->&H999L")
- obj = &H999L
- 'obj2 = New System.Decimal(666666)
- obj2 = 666.6666
- End Sub
- Public Sub Map_HResultAndException(
- <Out, MarshalAs(UnmanagedType.BStr)>
- ByRef Display As String
- ) Implements IUnregisterServer2.Map_HResultAndException
- MyTrace("Map_HResultAndException")
- 'Beep()
- Try
- Marshal.ThrowExceptionForHR(&H80040154)
- Catch ex As Exception
- Display = $"msg={ex.Message}"
- MyTrace(Display)
- Throw New MyException(&HA1110000, ex.Message & " -- Chen")
- End Try
- End Sub
- Public Sub Hello_world3(
- decimal2 As System.Decimal,
- guid As System.Guid,
- <Out, MarshalAs(UnmanagedType.BStr)> ByRef outputResult As String
- ) Implements IUnregisterServer2.Hello_world3
- outputResult =
- $" decimal= {decimal2} guid= {guid}"
- End Sub
- Sub QueryInterface2(
- <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
- <Out, MarshalAs(UnmanagedType.IUnknown)> ByRef ppVoid As Object) Implements IUnregisterServer2.QueryInterface2
- End Sub
- Sub AddRef2() Implements IUnregisterServer2.AddRef2
- End Sub
- Sub Release2() Implements IUnregisterServer2.Release2
- End Sub
- Sub GetTypeInfoCount2(
- <Out> ByRef out_UINT_pctinfo As UInt32) Implements IUnregisterServer2.GetTypeInfoCount2
- End Sub
- Sub GetTypeInfo2(
- itinfo As UInt32, lcid As UInt32,
- <Out, MarshalAs(UnmanagedType.Interface)> ByRef ppTInfo As Object
- ) Implements IUnregisterServer2.GetTypeInfo2
- End Sub
- Sub GetIDsOfNames2(
- <[In](), MarshalAs(UnmanagedType.LPStruct)> REFIID_riid As Guid,
- <[In](), MarshalAs(UnmanagedType.LPStr)> LPOLESTR_rgszNames As String,
- <[In]()> cNames As UInt32,
- <[In]()> LCID_lcid As UInt32,
- <Out> ByRef rgDispId As Int32) Implements IUnregisterServer2.GetIDsOfNames2
- End Sub
- Sub Invoke2(
- <[In]()> _In_DISPID_dispIdMember As Int32,
- <[In](), MarshalAs(UnmanagedType.LPStruct)> _In_REFIIDriid As Guid,
- <[In]()> _In_LCID_lcid As UInt32,
- <[In]()> _In_WORD_wFlags As UInt16,
- <[In]()> _In_pDispParams As IntPtr,
- <Out> ByRef _Out_opt_VARIANT_pVarResult As Object,
- <Out> ByRef _Out_opt_pExcepInfo As IntPtr,
- <Out> ByRef _Out_opt_puArgErr As UInt32) Implements IUnregisterServer2.Invoke2
- End Sub
- Public ReadOnly Property TraceMessage As String Implements IUnregisterServer2.TraceMessage
- Get
- TraceMessage = vbNewLine &
- "==== TraceMessage(Chen Inn-Jer) 2 ======" &
- vbNewLine & _TraceMessage.ToString() &
- "==== TraceMessage(Chen Inn-Jer) 2 ======" &
- vbNewLine
- _TraceMessage.Clear() : TraceSteps = 0
- End Get
- End Property
- Sub YYYY(<Out> ByRef intptr_obj As IntPtr) Implements IXXXX.YYYY
- intptr_obj = New IntPtr(12345678)
- MyTrace($"YYYY({intptr_obj})")
- End Sub
- Sub YYYY1(<[In], Out, MarshalAs(UnmanagedType.BStr)> ByRef Comment As String) Implements IXXXX.YYYY1
- MyTrace($"YYYY1 {Comment}")
- Dim MainType As Type = GetType(MyUnregisterServer2)
- Dim ThisModule As Reflection.Module = MainType.Module
- Dim peKind As Reflection.PortableExecutableKinds
- Dim machine As Reflection.ImageFileMachine
- ThisModule.GetPEKind(peKind, machine)
- Comment = "This is YYYY1 in MyUnregisterServer1" &
- vbNewLine & "MyLocation is " &
- Reflection.Assembly.GetExecutingAssembly.Location &
- vbNewLine & "FrameworkDescription is " &
- Runtime.InteropServices.RuntimeInformation.FrameworkDescription &
- vbNewLine & $"machine={machine} peKind={peKind}" &
- vbNewLine
- End Sub
- '2------------------------------------------------
- Dim TraceSteps As Int32
- Dim _TraceMessage As Text.StringBuilder
- Shared MyUnregisterServer2_Object As MyUnregisterServer2
- Shared Sub CreateObject3_Chen(ByRef IID As Guid,
- ppvoid_temp As IntPtr, Not_Used As IntPtr)
- If MyUnregisterServer2_Object Is Nothing Then
- MyUnregisterServer2_Object = New MyUnregisterServer2()
- End If
- MyUnregisterServer2_Object.MyTrace(
- $"MyUnregisterServer2 IID={IID} Not_Used = {Not_Used}")
- If IID = GetType(IUnregisterServer2).GUID Then
- Dim IUnregisteredInterface As IUnregisterServer2 =
- CType(MyUnregisterServer2_Object,
- IUnregisterServer2)
- Dim ppvoid As IntPtr = Marshal.GetIUnknownForObject(IUnregisteredInterface)
- Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
- Exit Sub
- ElseIf IID = GetType(IXXXX).GUID Then
- Dim IXXXXInterface As IXXXX =
- CType(MyUnregisterServer2_Object,
- IXXXX)
- Dim ppvoid As IntPtr = Marshal.GetIUnknownForObject(IXXXXInterface)
- Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
- Exit Sub
- End If
- MsgBox("Error:Nothing")
- End Sub
- Sub New()
- MyBase.New()
- _TraceMessage = New Text.StringBuilder(5 << 20)
- TraceSteps = 0
- End Sub
- Private Class MyException
- Inherits Exception
- Sub New(errorcode As Int32, Message As String)
- MyBase.New(Message)
- HResult = errorcode
- End Sub
- End Class
- Private Sub MyTrace(msg As String)
- TraceSteps += 1
- _TraceMessage.AppendLine($"{TraceSteps:d2} : {msg}")
- End Sub
- End Class
- #End If
- #include "pch.h"
- #include <stdio.h>
- #include <objbase.h>
- #include <windows.h>
- #include <Combaseapi.h>
- #include "oleauto.h"
- #include "propvarutil.h"
- #include "wtypes.h"
- #include <ctime>
- #include <exception>
- #include <typeinfo>
- #include "TestParameter.h"
- #if defined(_M_AMD64) && defined(_WIN64) && defined(_WINDOWS) && \
- defined(_USRDLL) && _MSVC_LANG >= 202002L
- extern "C" /* exported functions */ {
- int CPP_DLL_Test_UnregisteredServer1(TestParameter*);
- int CPP_DLL_Test_UnregisteredServer2(TestParameter*);
- int CPP_DLL_Test_IXXXX(TestParameter*);
- }
- IUnknown* pIUnknown;
- HRESULT hr;
- template <class T> concept Is_BSTR_v = std::is_convertible_v<T, BSTR>;
- template <class T> concept Is_LPCOLESTR_v = std::is_convertible_v<LPCOLESTR, T>;
- template <typename T>
- struct ServerInfo_Struct {
- T AssemblyPath;
- T TypeFullName;
- T CreationMethod;
- T CLSID;
- T IID;
- ServerInfo_Struct(T t1, T t2, T t3, T t4, T t5) :
- AssemblyPath(t1),
- TypeFullName(t2),
- CreationMethod(t3),
- CLSID(t4),
- IID(t5) {
- }
- ServerInfo_Struct& operator=(ServerInfo_Struct&) = delete;
- ServerInfo_Struct(const ServerInfo_Struct&) = delete;
- ~ServerInfo_Struct() requires Is_BSTR_v<T> {
- if (0 == strcmp(typeid(T).name(), typeid(BSTR).name())) {
- printf("std::is_convertible_v< %s , %s >\n",
- typeid(T).name(), typeid(BSTR).name());
- }
- else printf("===> Error:%s\n", typeid(T).name());
- ::SysFreeString((wchar_t*)AssemblyPath);
- ::SysFreeString((wchar_t*)TypeFullName);
- ::SysFreeString((wchar_t*)CreationMethod);
- ::SysFreeString((wchar_t*)CLSID);
- ::SysFreeString((wchar_t*)IID);
- }
- ~ServerInfo_Struct()requires Is_LPCOLESTR_v<T> {
- puts(typeid(T).name());
- if (0 == strcmp(typeid(LPCOLESTR).name(), typeid(T).name())) {
- printf("std::is_convertible_v< %s , %s >\n",
- typeid(LPCOLESTR).name(), typeid(T).name());
- }
- else printf("===> Error:%s\n", typeid(T).name());
- }
- };
- template ServerInfo_Struct<LPCOLESTR>;
- template ServerInfo_Struct<BSTR>;
- #ifdef _DEBUG
- const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
- "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Debug\\NotRegisteredServer.dll"
- );
- #else
- const LPCOLESTR MyServerName = (LPCOLESTR)OLESTR(
- "NotRegisteredServer\\NotRegisteredServer\\bin\\x64\\Release\\NotRegisteredServer.dll"
- );
- #endif
- ServerInfo_Struct<LPCOLESTR> My_Server_string[] = {
- {
- MyServerName,
- (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer1"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("04D9F530-CE0C-4232-8F3F-6E0A3244C715"),
- (LPCOLESTR)OLESTR("31D53FF8-4768-4A77-95E3-DC28DEBB375F")
- },{
- MyServerName,
- (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
- (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
- },{
- MyServerName,
- (LPCOLESTR)OLESTR("NotRegisteredServer.MyUnregisterServer2"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
- (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
- }
- };
- int Get_ServerInterface(TestParameter* ptr, int interfaceID
- , PVOID* pRetVal) {
- ICreationInstance* Ptr_Creation_Instance =
- (ICreationInstance*)ptr->ptr_to_Interface;
- ServerInfo_Struct<LPCOLESTR>& MyServerString = My_Server_string[interfaceID];
- ServerInfo_Struct<BSTR> My_Server{
- SysAllocString(ToFullPath(ptr->PathRoot,MyServerString.AssemblyPath)),
- SysAllocString(MyServerString.TypeFullName),
- SysAllocString(MyServerString.CreationMethod),
- SysAllocString(MyServerString.CLSID),
- SysAllocString(MyServerString.IID)
- };
- hr = Ptr_Creation_Instance->Get_Interface3(&My_Server, (PVOID*)&pIUnknown);
- if (FAILED(hr))return -31;
- IID myiid2;
- hr = IIDFromString(AddCurlyBracket(My_Server.IID), &myiid2);
- if (FAILED(hr))return -32;
- hr = pIUnknown->QueryInterface(myiid2, pRetVal);
- if (FAILED(hr))return -33;
- return 0;
- }
- /* Begin CPP_DLL_Test_UnregisteredServer1 */
- void This_Delegate_will_be_called_While_RaiseEvent(VARIANTARG VAR) {
- ExportedData::MySelf()->WriteLine(L"This_Delegate_will_be_called_While_RaiseEvent(VT_BSTR=%d V_VT(&VAR)=%d)",
- VT_BSTR, V_VT(&VAR));
- ExportedData::MySelf()->WriteLine(L"<@%s@>", V_BSTR(&VAR));
- }
- __interface IUnregisteredServer1 :IDispatch
- {
- HRESULT Get_Interface(PVOID*);
- HRESULT Get_Interface2(long, VARIANTARG*);
- HRESULT Register_Event(void (*)(VARIANT), BSTR, INT32* ID);
- HRESULT RemoveEvent(INT32 ID);
- HRESULT Raise_Event(LONG64);
- HRESULT Get_MyProperty(INT32*);
- HRESULT Put_MyProperty(INT32 pRetVal);
- HRESULT GetTraceMessage(BSTR*);
- };
- int CPP_DLL_Test_UnregisteredServer1(TestParameter* ptr) {
- ExportedData ED(ptr, L"CPP_DLL_Test_UnregisteredServer1");
- IUnregisteredServer1* pIUnregisteredServer1;
- int rv = Get_ServerInterface(ptr, 0, (PVOID*)&pIUnregisteredServer1);
- if (rv < 0)return rv;
- INT32 _INT32 = 777;
- ED.WriteLine(L"(%d)", _INT32);
- pIUnregisteredServer1->Get_MyProperty(&_INT32);
- ED.WriteLine(L"(%d)", _INT32);
- INT32 EventID[3]{};
- BSTR MyString_BSTR = SysAllocString(L"Register_Event(&This_Delegate_will_be_called_While_RaiseEvent, MyString_BSTR)");
- for (INT64 aa = 21; aa < 25; aa++) {
- for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
- pIUnregisteredServer1->Register_Event(&This_Delegate_will_be_called_While_RaiseEvent,
- MyString_BSTR, &EventID[bb]);
- }
- pIUnregisteredServer1->Raise_Event(aa);
- for (INT32 bb = 0; bb < sizeof(EventID) / sizeof(EventID[0]); bb++) {
- pIUnregisteredServer1->RemoveEvent(EventID[bb]);
- }
- }
- ::SysFreeString(MyString_BSTR);
- IUnknown* _ptr2_;
- pIUnregisteredServer1->Get_Interface((PVOID*)&_ptr2_);
- if (pIUnknown != _ptr2_) {
- ED.WriteLine(L"Error1:%p", pIUnknown);
- ED.WriteLine(L"Error1:%p", _ptr2_);
- }
- VARIANT _variant;
- VariantInit(&_variant);
- pIUnregisteredServer1->Get_Interface2(2, &_variant);
- if (V_VT(&_variant) != VT_UNKNOWN) {
- ED.WriteLine(L"error: V_VT(&_variant)=%d", V_VT(&_variant));
- }
- _ptr2_ = V_DISPATCH(&_variant);
- if (pIUnknown != _ptr2_) {
- ED.WriteLine(L"Error2:%p", pIUnknown);
- ED.WriteLine(L"Error2:%p", _ptr2_);
- }
- BSTR MyMessage = NULL;
- pIUnregisteredServer1->GetTraceMessage(&MyMessage);
- ED.WriteLine(L"GetTraceMessage");
- ED.WriteLine(L"%s", MyMessage);
- SysFreeString(MyMessage);
- return 0;
- }
- /* End CPP_DLL_Test_UnregisteredServer1 */
- // 1 ======================================================= 2
- /* Begin CPP_DLL_Test_UnregisteredServer2 */
- __interface IUnregisteredServer2_CPP :public IDispatch
- {
- public:
- HRESULT DefaultMarshallingForObject(VARIANT* v, VARIANT* v2, VARIANT* v3);
- HRESULT Map_HResultAndException(BSTR* display);
- HRESULT Hello_world3(
- DECIMAL decimal2,
- GUID guid2,
- BSTR* outputResult
- );
- virtual HRESULT STDMETHODCALLTYPE QueryInterface2(
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void** ppvObject) = 0;
- virtual ULONG STDMETHODCALLTYPE AddRef2(void) = 0;
- virtual ULONG STDMETHODCALLTYPE Release2(void) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount2(
- /* [out] */ __RPC__out UINT* pctinfo) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetTypeInfo2(
- /* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames2(
- /* [in] */ __RPC__in REFIID riid,
- /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
- /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId) = 0;
- virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke2(
- /* [annotation][in] */
- _In_ DISPID dispIdMember,
- /* [annotation][in] */
- _In_ REFIID riid,
- /* [annotation][in] */
- _In_ LCID lcid,
- /* [annotation][in] */
- _In_ WORD wFlags,
- /* [annotation][out][in] */
- _In_ DISPPARAMS* pDispParams,
- /* [annotation][out] */
- _Out_opt_ VARIANT* pVarResult,
- /* [annotation][out] */
- _Out_opt_ EXCEPINFO* pExcepInfo,
- /* [annotation][out] */
- _Out_opt_ UINT* puArgErr) = 0;
- virtual HRESULT STDMETHODCALLTYPE GetTraceMessage(BSTR*) = 0;
- };
- extern "C" {
- /* [unique][uuid][object] */
- typedef interface IUnregisteredServer2_C IUnregisteredServer2_C;
- typedef struct IUnregisteredServer2_CVtbl
- {
- BEGIN_INTERFACE
- HRESULT(STDMETHODCALLTYPE* QueryInterface)(
- __RPC__in IDispatch* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void** ppvObject);
- ULONG(STDMETHODCALLTYPE* AddRef)(
- __RPC__in IUnregisteredServer2_C* This);
- ULONG(STDMETHODCALLTYPE* Release)(
- __RPC__in IUnregisteredServer2_C* This);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [out] */ __RPC__out UINT* pctinfo);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfo)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);
- HRESULT(STDMETHODCALLTYPE* GetIDsOfNames)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
- /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke)(
- IUnregisteredServer2_C* This,
- /* [annotation][in] */
- _In_ DISPID dispIdMember,
- /* [annotation][in] */
- _In_ REFIID riid,
- /* [annotation][in] */
- _In_ LCID lcid,
- /* [annotation][in] */
- _In_ WORD wFlags,
- /* [annotation][out][in] */
- _In_ DISPPARAMS* pDispParams,
- /* [annotation][out] */
- _Out_opt_ VARIANT* pVarResult,
- /* [annotation][out] */
- _Out_opt_ EXCEPINFO* pExcepInfo,
- /* [annotation][out] */
- _Out_opt_ UINT* puArgErr);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* DefaultMarshallingForObject)(
- __RPC__in IUnregisteredServer2_C* This,
- VARIANT* v,
- VARIANT* v2,
- VARIANT* v3
- );
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Map_HResultAndException)(
- __RPC__in IUnregisteredServer2_C* This, BSTR* Display
- );
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Hello_world3)(
- __RPC__in IUnregisteredServer2_C* This,
- DECIMAL decimal2,
- GUID guid2,
- BSTR* outputResult
- );
- HRESULT(STDMETHODCALLTYPE* QueryInterface2)(
- __RPC__in IDispatch* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void** ppvObject);
- ULONG(STDMETHODCALLTYPE* AddRef2)(
- __RPC__in IUnregisteredServer2_C* This);
- ULONG(STDMETHODCALLTYPE* Release2)(
- __RPC__in IUnregisteredServer2_C* This);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfoCount2)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [out] */ __RPC__out UINT* pctinfo);
- HRESULT(STDMETHODCALLTYPE* GetTypeInfo2)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ UINT iTInfo,
- /* [in] */ LCID lcid,
- /* [out] */ __RPC__deref_out_opt ITypeInfo** ppTInfo);
- HRESULT(STDMETHODCALLTYPE* GetIDsOfNames2)(
- __RPC__in IUnregisteredServer2_C* This,
- /* [in] */ __RPC__in REFIID riid,
- /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR* rgszNames,
- /* [range][in] */ __RPC__in_range(0, 16384) UINT cNames,
- /* [in] */ LCID lcid,
- /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID* rgDispId);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* Invoke2)(
- IUnregisteredServer2_C* This,
- /* [annotation][in] */
- _In_ DISPID dispIdMember,
- /* [annotation][in] */
- _In_ REFIID riid,
- /* [annotation][in] */
- _In_ LCID lcid,
- /* [annotation][in] */
- _In_ WORD wFlags,
- /* [annotation][out][in] */
- _In_ DISPPARAMS* pDispParams,
- /* [annotation][out] */
- _Out_opt_ VARIANT* pVarResult,
- /* [annotation][out] */
- _Out_opt_ EXCEPINFO* pExcepInfo,
- /* [annotation][out] */
- _Out_opt_ UINT* puArgErr);
- /* [local] */ HRESULT(STDMETHODCALLTYPE* GetTraceMessage)(
- __RPC__in IUnregisteredServer2_C* This, BSTR*
- );
- END_INTERFACE
- } IUnregisteredServer2_CVtbl;
- interface IUnregisteredServer2_C
- {
- CONST_VTBL struct IUnregisteredServer2_CVtbl* lpVtbl;
- };
- #define IUnregisteredServer2_C_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
- #define IUnregisteredServer2_C_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
- #define IUnregisteredServer2_C_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
- #define IUnregisteredServer2_C_GetTypeInfoCount(This,pctinfo) \
- ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) )
- #define IUnregisteredServer2_C_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
- ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) )
- #define IUnregisteredServer2_C_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \
- ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) )
- #define IUnregisteredServer2_C_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
- ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) )
- #define IUnregisteredServer2_C_DefaultMarshallingForObject(This,variant,v2,v3) \
- ( (This)->lpVtbl -> DefaultMarshallingForObject(This,variant,v2,v3) )
- }
- int CPP_DLL_Test_UnregisteredServer2(TestParameter* ptr) {
- ExportedData ED(ptr, L"CPP_DLL_Test_UnregisteredServer2");
- IUnregisteredServer2_CPP* pIUnregisteredServer2_CPP;
- int rv = Get_ServerInterface(ptr, 1, (PVOID*)&pIUnregisteredServer2_CPP);
- if (rv < 0)return rv;
- VARIANT v, v2, v3;
- VariantInit(&v); VariantInit(&v2); VariantInit(&v3);
- InitVariantFromInt32(0x12345, &v);
- ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
- pIUnregisteredServer2_CPP->DefaultMarshallingForObject(&v, &v2, &v3);
- if (V_VT(&v) != VT_I8) return -3005;
- ED.WriteLine(L"V_VT(&v)=%d %X ", V_VT(&v), V_I8(&v));
- ED.WriteLine(L"V_VT(&v2)=%d %f ", V_VT(&v2), V_R8(&v2));
- DECIMAL d{ };
- GUID g;
- d.Lo32 = 6666666; d.scale = 3;
- hr = CLSIDFromString(OLESTR("{45A82A95-6446-43F0-83B9-71E7469E14D2}"),
- &g);
- if (FAILED(hr)) return -3008;
- BSTR outputResult = NULL;
- pIUnregisteredServer2_CPP->Hello_world3(d, g,
- &outputResult);
- ED.WriteLine(L"outputResult %s", outputResult);
- ::SysFreeString(outputResult);
- IUnregisteredServer2_C* pIUnregisteredServer2_C =
- (IUnregisteredServer2_C*)pIUnregisteredServer2_CPP;
- if ((void*)pIUnregisteredServer2_CPP != (void*)pIUnregisteredServer2_C) {
- ED.WriteLine(L"pIUnregisteredServer2_CPP=%p", pIUnregisteredServer2_CPP);
- ED.WriteLine(L"pIUnregisteredServer2_C =%p", pIUnregisteredServer2_C);
- }
- VariantInit(&v);
- VariantInit(&v2);
- VariantInit(&v3);
- InitVariantFromInt32(321, &v);
- for (int aa = 0; aa < 1; aa++) {
- IUnregisteredServer2_C_DefaultMarshallingForObject(
- pIUnregisteredServer2_C, &v, &v2, &v3);
- ED.WriteLine(L"V_VT(&v)=%d %X", V_VT(&v), V_I8(&v));
- }
- BSTR Display = NULL;
- hr = pIUnregisteredServer2_C->lpVtbl->Map_HResultAndException(
- pIUnregisteredServer2_C, &Display);
- ED.WriteLine(L"hr=0X%X", hr);
- ED.WriteLine(L"Display=%s", Display);
- if (Display) ::SysFreeString(Display);
- ED.WriteLine(L"sizeof(lpVtbl)=%d", sizeof(pIUnregisteredServer2_C->lpVtbl));
- BSTR MyMessage = NULL;
- pIUnregisteredServer2_C->lpVtbl->GetTraceMessage(
- pIUnregisteredServer2_C, &MyMessage);
- ED.WriteLine(L"GetTraceMessage");
- ED.WriteLine(L"%s", MyMessage);
- SysFreeString(MyMessage);
- return 0;
- }
- /* End CPP_DLL_Test_UnregisteredServer2 */
- // 2 ================================================= 3
- /* Begin CPP_DLL_Test_IXXXX */
- __interface IXXXX :public IUnregisteredServer2_CPP
- {
- HRESULT YYYY(INT64*);
- HRESULT YYYY1(BSTR*);
- };
- int CPP_DLL_Test_IXXXX(TestParameter* ptr) {
- ExportedData ED(ptr, L"CPP_DLL_Test_IXXXX");
- IXXXX* pIXXXX;
- int rv = Get_ServerInterface(ptr, 2, (PVOID*)&pIXXXX);
- if (rv < 0)return rv;
- INT64 aaa;
- pIXXXX->YYYY(&aaa);
- ED.WriteLine(L"aaa = %d", aaa);
- BSTR comment = ::SysAllocString(L" ABC ");
- pIXXXX->YYYY1(&comment);
- ED.WriteLine(L"comment=%s", comment);
- ::SysFreeString(comment);
- BSTR Trace = NULL;
- pIXXXX->GetTraceMessage(&Trace);
- ED.WriteLine(L"%s", Trace);
- ::SysFreeString(Trace);
- return 0;
- }
- /* End CPP_DLL_Test_IXXXX */
- #endif
- LIBRARY
- EXPORTS
- CPP_DLL_Test_UnregisteredServer1 @1
- CPP_DLL_Test_UnregisteredServer2 @2
- CPP_DLL_Test_IXXXX @3

































































































































留言
張貼留言