Interop Marshalling
- #pragma once
- #ifndef For_Pch
- #define For_Pch
- #include "Windows.h"
- #include "PathCch.h"
- #include "strsafe.h"
- #include "objbase.h"
- #include "Combaseapi.h"
- #include "oleauto.h"
- #include "propvarutil.h"
- #include "wtypes.h"
- #include "stdio.h"
- #include "ctime"
- #include "exception"
- #include "typeinfo"
- #include "shlwapi.h"
- #include "Psapi.h"
- #include "stdexcept"
- #include "stdarg.h"
- #include "comdef.h"
- #include <algorithm>
- #include <vector>
- #include <type_traits>
- #include <concepts>
- #include <atlbase.h>
- #include <atlcom.h>
- #include <memory>
- #endif // !For_Pch
- #pragma once
- #include "For_Pch.h"
- #ifdef _DEBUG
- # define My_Configuration Debug
- #else
- # define My_Configuration Release
- #endif
- #define Stringizing_To_raw_string_w(arg) LR#arg
- #define Stringizing_To_raw_string(arg) R#arg
- #define Add_Deliniter_w(str) Stringizing_To_raw_string_w( ***( ## str ## )*** )
- #define Add_Deliniter(str) Stringizing_To_raw_string( ***( ## str ## )*** )
- #define Expand_Macro_Parameter_definition3_w(A,B,C) Add_Deliniter_w( A ## B ## C )
- #define Expand_Macro_Parameter_definition3(A,B,C) Add_Deliniter( A ## B ## C )
- #define Expand_Macro_Parameter_definition1_w(A) Add_Deliniter_w(A)
- #define Expand_Macro_Parameter_definition1(A) Add_Deliniter( A)
- #define Server_Name_w(rr,Config_be_Expanded,ss) Expand_Macro_Parameter_definition3_w(rr,Config_be_Expanded,ss)
- #define Server_Name( rr,Config_be_Expanded,ss) Expand_Macro_Parameter_definition3( rr,Config_be_Expanded,ss)
- #define DLL_Name_w(rr,Config_be_Expanded,ss) Expand_Macro_Parameter_definition3_w(rr,Config_be_Expanded,ss)
- #define DLL_Name( rr,Config_be_Expanded,ss) Expand_Macro_Parameter_definition3( rr,Config_be_Expanded,ss)
- #define Raw_string_w(str) Expand_Macro_Parameter_definition1_w(str)
- #define Raw_string(str) Expand_Macro_Parameter_definition1(str)
- #define Lib_Name_inside(rr,Config_be_Expanded,ss) Expand_Macro_Parameter_definition3(rr,Config_be_Expanded,ss)
- #define Lib_Name_outside(rr,Config_be_Expanded,ss) Expand_Macro_Parameter_definition3(rr,Config_be_Expanded,ss)
- #pragma comment(lib,Lib_Name_outside(..\..\StaticLib_Marshalling\x64\,My_Configuration,\StaticLib_Marshalling))
- #pragma comment(lib,"PathCch")
- __interface ICreationInstance :IDispatch
- {
- HRESULT Get_Interface3(
- _In_ PVOID AssemblyInfo_ptr,
- _COM_Outptr_ PVOID* ppvid);
- HRESULT GetDescription(
- _In_ BSTR description);
- HRESULT GetDescription2(
- _Out_ BSTR* description);
- HRESULT Get_Interface4(
- PVOID AssemblyInfo_ptr,
- VARIANT* ppVoid_object);
- };
- typedef void (*MyWriteLine)(const WCHAR* format, va_list);
- struct TestParameter {
- MyWriteLine MyWriteLine;
- PVOID ptr_to_Interface;
- const WCHAR* PathRoot;
- };
- class ExportedData {
- MyWriteLine MyWriteLine;
- const WCHAR* start;
- va_list My_va_list;
- static inline ExportedData* ED_ptr = nullptr;
- public:
- static 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;
- }
- };
- #define PAUSE system("pause");
- #define HR_(Express,errorCode) \
- try { My_Message((Express),(errorCode), __FILEW__, __LINE__, __FUNCTIONW__);} \
- catch (const std::exception & ) { return errorCode ; }
- #define RETURN(retVal) return My_RETURN(retVal, __FILEW__ , __LINE__ , __FUNCTIONW__);
- 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=(const 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());
- }
- };
- const WCHAR* AddCurlyBracket(const WCHAR* uuid);
- const WCHAR* ToFullPath(const WCHAR* pRoot, const WCHAR* relativePath);
- void My_Message(HRESULT hr2, int errorCode, LPCWSTR file_, int Line_, const wchar_t* fn);
- int My_RETURN(int retVal, LPCWSTR file_, int Line_, const wchar_t* fn);
- int Get_ServerInterface4(TestParameter* ptr,
- ServerInfo_Struct<LPCOLESTR>& MyServerString, PVOID* pRetVal);
- int Get_ServerInterface(TestParameter* ptr,
- ServerInfo_Struct<LPCOLESTR>& MyServerString, PVOID* pRetVal);
- int SetErrorInfo_Chen(const WCHAR* Description, const WCHAR* source);
- // StaticLib_Marshalling.cpp : Defines the functions for the static library.
- //
- #include "pch.h"
- #include "framework.h"
- #include "TestParameter.h"
- 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_);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];
- }
- //==================================================
- int Get_ServerInterface(TestParameter* ptr,
- ServerInfo_Struct<LPCOLESTR>& MyServerString, PVOID* pRetVal) {
- ServerInfo_Struct<BSTR> My_Server{
- SysAllocString(ToFullPath(ptr->PathRoot,MyServerString.AssemblyPath)),
- SysAllocString(MyServerString.TypeFullName),
- SysAllocString(MyServerString.CreationMethod),
- SysAllocString(MyServerString.CLSID),
- SysAllocString(MyServerString.IID)
- };
- ICreationInstance* Ptr_Creation_Instance;
- IUnknown* pIUnknown;
- IID myiid2;
- Ptr_Creation_Instance = (ICreationInstance*)ptr->ptr_to_Interface;
- HR_(Ptr_Creation_Instance->Get_Interface3(&My_Server, (PVOID*)&pIUnknown), 31)
- HR_(IIDFromString(AddCurlyBracket(My_Server.IID), &myiid2), 32)
- HR_(pIUnknown->QueryInterface(myiid2, pRetVal), 33)
- pIUnknown->Release();
- return 0;
- }
- int Get_ServerInterface4(TestParameter* ptr,
- ServerInfo_Struct<LPCOLESTR>& MyServerString, PVOID* pRetVal) {
- IUnknown* pIUnknown;
- IDispatch* pIDispatch;
- VARIANT Variant;
- IID myiid;
- ICreationInstance* pICreationInstance;
- ServerInfo_Struct<BSTR> My_Server{
- SysAllocString(ToFullPath(ptr->PathRoot,MyServerString.AssemblyPath)),
- SysAllocString(MyServerString.TypeFullName),
- SysAllocString(MyServerString.CreationMethod),
- SysAllocString(MyServerString.CLSID),
- SysAllocString(MyServerString.IID)
- };
- pICreationInstance = (ICreationInstance*)ptr->ptr_to_Interface;
- VariantInit(&Variant);
- HR_(pICreationInstance->Get_Interface4(&My_Server, &Variant), 31)
- HR_(IIDFromString(AddCurlyBracket(My_Server.IID), &myiid), 32)
- if (V_VT(&Variant) == VT_UNKNOWN) {
- pIUnknown = V_UNKNOWN(&Variant);
- HR_(pIUnknown->QueryInterface(myiid, pRetVal), 33)
- HR_(pIUnknown->QueryInterface(IID_IDispatch, (void**)&pIDispatch), 34)
- printf("V_VT(&Variant) == VT_UNKNOWN\n");
- }
- else if (V_VT(&Variant) == VT_DISPATCH) {
- pIDispatch = V_DISPATCH(&Variant);
- HR_(pIDispatch->QueryInterface(myiid, pRetVal), 35)
- HR_(pIDispatch->QueryInterface(IID_IUnknown, (void**)&pIUnknown), 36)
- printf("V_VT(&Variant) == VT_DISPATCH\n");
- }
- else {
- printf("V_VT(&_variant)= %d\n", V_VT(&Variant));
- RETURN(39);
- }
- printf("(pIUnknown = %p)\n(pIDispatch = %p)\n(*pRetVal = %p)\n",
- pIUnknown, pIDispatch, *pRetVal);
- printf("(%d)pIUnknown->Release()\n", pIUnknown->Release());
- printf("(%d)pIDispatch->Release()\n", pIDispatch->Release());
- PAUSE
- return 0;
- }
- void My_Message(HRESULT hr2, int errorCode, LPCWSTR file_, int Line_, const wchar_t* fn) {
- if (FAILED(hr2)) {
- IErrorInfo* pIErrorInfo = NULL;
- HRESULT hr = GetErrorInfo(0, &pIErrorInfo);
- _com_error hr_err(hr2);
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_RED);
- printf(" %S\n Line=%i fn=%S\n", file_, Line_, fn);
- printf("hr=%x (%S)\n", unsigned(hr2), hr_err.ErrorMessage());
- if (SUCCEEDED(hr) && pIErrorInfo) {
- BSTR Description, source;
- pIErrorInfo->GetDescription(&Description);
- pIErrorInfo->GetSource(&source);
- printf("Description=%S\n", Description);
- printf("Source=%S\n", source);
- SysFreeString(Description); SysFreeString(source);
- pIErrorInfo->Release();
- }
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
- FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
- throw std::exception("Exception from procedure(My_Message)");
- }
- }
- int My_RETURN(int retVal, LPCWSTR file_, int Line_, const wchar_t* fn) {
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);
- printf(" %S\n Line=%i fn=%S\n", file_, Line_, fn);
- printf("return value = %i\n", retVal);
- SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
- FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
- return retVal;
- };
- int SetErrorInfo_Chen(const WCHAR* Description,
- const WCHAR* source) {
- ICreateErrorInfo* pICreateErrorInfo;
- IErrorInfo* pIErrorInfo;
- HRESULT hr;
- hr = CreateErrorInfo(&pICreateErrorInfo);
- if (SUCCEEDED(hr)) {
- hr = pICreateErrorInfo->QueryInterface(IID_IErrorInfo, (void**)&pIErrorInfo);
- if (SUCCEEDED(hr)) {
- const size_t size_MAX = 4000;
- size_t size;
- WCHAR* Tmp_Str = new WCHAR[size_MAX + 1];
- hr = StringCchLengthW(Description, size_MAX, &size);
- if (FAILED(hr) || size >= size_MAX)return -12;
- StringCchCopyW(Tmp_Str, size_MAX, Description);
- pICreateErrorInfo->SetDescription(Tmp_Str);
- hr = StringCchLengthW(source, size_MAX, &size);
- if (FAILED(hr) || size >= size_MAX)return -13;
- StringCchCopyW(Tmp_Str, size_MAX, source);
- pICreateErrorInfo->SetSource(Tmp_Str);
- delete[]Tmp_Str;
- SetErrorInfo(0, pIErrorInfo);
- pIErrorInfo->Release();
- }
- else return -1;
- pICreateErrorInfo->Release();
- }
- else return -2;
- return 0;
- }
- #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 =====> CPP");
- }
- #if defined(_M_X64) && defined(_WIN64) && defined(_CONSOLE) && \
- _MSVC_LANG >= 201703L
- #include "TestParameter.h"
- #pragma comment(lib,Lib_Name_inside(..\x64\,My_Configuration,\Create_dotNET_Platform))
- //#pragma comment(linker,Raw_string(/ENTRY:mainCRTStartup))
- /*
- #pragma comment(linker,"/LIBPATH:C:\Users\Networker")
- $(SolutionDir)= C:\Users\Networker\Desktop\CPP_Main_Test_Marshalling_Project\
- $(ProjectDir)= C:\Users\Networker\Desktop\CPP_Main_Test_Marshalling_Project\CPP_Main_Test_Marshalling_Project\
- $(TargetDir)= C:\Users\Networker\Desktop\CPP_Main_Test_Marshalling_Project\x64\Debug\
- $(USERPROFIL)= C:\Users\Networker
- $(HOMEPATH)= \Users\Networker
- %(AdditionalLibraryDirectories)
- */
- #define AfxLoadLibrary LoadLibraryW
- #define AfxFreeLibrary FreeLibrary
- #define CreationInstance_clsid OLESTR("91DD12FD-4DBD-4B83-AC40-439E3B6393A1")
- #define CreationInstance_iid OLESTR("85927839-0BB2-423B-97D6-89A2D4002519")
- #define LeadingLibrary_clsid OLESTR("2B6E5DB5-CF45-40B8-8091-55027E408231")
- #define LeadingLibrary_IID OLESTR("16142434-D1CF-4DC8-BD7B-7E5091058490")
- namespace Chen {
- int My_Console_Main(const wchar_t* comment);
- LPCWSTR LeadingLibraryRelativePath = Server_Name_w(LeadingLibraryForLoadingDLL\LeadingLibraryForLoadingDLL\bin\x64\,
- My_Configuration, \net9.0\LeadingLibraryForLoadingDLL.dll);
- LPCWSTR MyDll_CSharp = DLL_Name_w(CPP_DLL_Test_CSharp_Server\x64\,
- My_Configuration, \CPP_DLL_Test_CSharp_Server.dll);
- LPCWSTR MyDllname2_dotNET = DLL_Name_w(CPP_Dll_Test_Marshalling_dotNET\x64\,
- My_Configuration, \CPP_Dll_Test_Marshalling_dotNET.dll);
- LPCWSTR MyDllname3_dotNET = DLL_Name_w(CPP_DLL_Test_Multi_Interface\x64\,
- My_Configuration, \CPP_DLL_Test_Multi_Interface.dll);
- #ifdef _DEBUG
- LPCWSTR MyDllname =
- Raw_string_w(MFC_DLL_Test_Marshalling\x64\Debug\MFCDLLTestMarshalling.dll);
- LPCWSTR MyDllname2 =
- Raw_string_w(CPP_Dll_Test_Marshalling\x64\Debug\CPP_Dll_Test_Marshalling.dll);
- #else
- LPCWSTR MyDllname =
- L"MFC_DLL_Test_Marshalling\\x64\\Release\\MFCDLLTestMarshalling.dll";
- 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;
- HMODULE hModule;
- } ClientInfo_Struct;
- ClientInfo_Struct ClientInfo_dotNET[]{
- {
- MyDll_CSharp,
- "CPP_DLL_Test_CSharp_Server",
- false
- },{
- MyDllname3_dotNET,
- "CPP_DLL_Test_MultiInterface",
- false
- },{
- MyDllname2_dotNET,
- "CPP_DLL_Test_UnregisteredServer1",
- false
- },{
- MyDllname2_dotNET,
- "CPP_DLL_Test_UnregisteredServer2",
- false
- },{
- MyDllname2_dotNET,
- "CPP_DLL_Test_IXXXX",
- false
- }
- };
- 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
- }
- };
- int Get_CreationInstance_To_Create_FollowingServer(
- LPCOLESTR LeadingLibrary_AbsolutePath,
- LPCOLESTR CLSID_String,
- LPCOLESTR IID_String);
- void Get_CreationInstance_To_Create_UnregisteredServer(
- LPCOLESTR CLSID_String,
- LPCOLESTR IID_String);
- int My_Test_Function_dotNET();
- int My_Test_Function();
- void MyEnumModules();
- void ReleaseResource_dotNET();
- 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];
- size_t MyPathRoot_Len;
- HANDLE hThread;
- DWORD ProcessID;
- HANDLE hProcess;
- IUnknown* pIUnknown_dotNET;
- ICreationInstance* pICreationInstance_dotNET;
- IUnknown* pIUnknown;
- ICreationInstance* pICreationInstance;
- const bool b_FreeLibrary = false; //true;
- void MyEnumModules() {
- struct Modules
- {
- std::wstring Name;
- HMODULE hModule;
- };
- const size_t hModuleSize = 1000;
- static HMODULE hModule_Chen[hModuleSize];
- static WCHAR ModuleName[NTFS_MAX_PATH];
- if (!hProcess) return;
- DWORD cbNeeded = 0;
- std::vector<struct Modules> MyModules;
- std::vector<struct Modules> Modules_system;
- auto GetAllModules = [&] {
- MyModules.clear(); Modules_system.clear();
- if (!K32EnumProcessModules(hProcess, hModule_Chen,
- DWORD(hModuleSize * sizeof(HMODULE)), &cbNeeded)) {
- ErrorMessage("error: K32EnumProcessModules "); return;
- }
- int32_t CountOfModules = cbNeeded / sizeof(HMODULE);
- for (int i = 0; i < CountOfModules; i++) {
- HMODULE hModule = hModule_Chen[i];
- GetModuleFileNameExW(hProcess, hModule, ModuleName, NTFS_MAX_PATH);
- if (_wcsnicmp(ModuleName, MyPathRoot, MyPathRoot_Len) == 0)
- MyModules.push_back(Modules(ModuleName, hModule));
- else Modules_system.push_back(Modules(ModuleName, hModule));
- }
- std::sort(MyModules.begin(), MyModules.end(), [](Modules A, Modules B)
- {return A.hModule < B.hModule; });
- std::sort(Modules_system.begin(), Modules_system.end(), [](Modules A, Modules B)
- {return _wcsicmp(A.Name.c_str(), B.Name.c_str()) < 0; });
- };
- auto FreeLib = [&] {
- for (int aa = 0; aa < ARRAYSIZE(ClientInfo_dotNET); aa++) {
- BOOL FreeLib_OK = (ClientInfo_dotNET[aa].MFC_DLL ?
- AfxFreeLibrary : FreeLibrary)(ClientInfo_dotNET[aa].hModule);
- LPCWSTR DLL_Name = ClientInfo_dotNET[aa].DLL_Path;
- if (FreeLib_OK)
- MyWriteLine(L" FreeLibrary OK %s\n", DLL_Name);
- else
- MyWriteLine(L" error: FreeLibrary %s\n", DLL_Name);
- }
- for (int aa = 0; aa < ARRAYSIZE(ClientInfo); aa++) {
- BOOL FreeLib_OK = (ClientInfo[aa].MFC_DLL ?
- AfxFreeLibrary : FreeLibrary)(ClientInfo[aa].hModule);
- 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);
- }
- };
- auto DisplayModules = [&] {
- auto SimplePtr = [](HMODULE xptr) { return UINT64(xptr) >> 16; };
- int count = 0;
- for (int j = 0; j < Modules_system.size(); j++) {
- Modules& t = Modules_system.at(j);
- printf("%2i %12llX %S\n", ++count, SimplePtr(t.hModule), t.Name.c_str());
- }
- for (int j = 0; j < MyModules.size(); j++) {
- Modules& t = MyModules.at(j);
- printf("%2i %12I64X %S\n", ++count, SimplePtr(t.hModule), t.Name.c_str() + MyPathRoot_Len);
- }
- printf("========= Count(%I32i) ==========\n", count);
- };
- GetAllModules();
- FreeLib();
- DisplayModules();
- GetAllModules();
- DisplayModules();
- }
- int AppInitialize() {
- #define MyFMT "\t%S\n"
- GetCurrentDirectoryW(NTFS_MAX_PATH, Current_Directory);
- printf("CurrentDir =" MyFMT, Current_Directory);
- 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"..\\..\\..\\"), 1002)
- PathCchAddBackslash(MyPathRoot, NTFS_MAX_PATH);
- printf("MyPathRoot=" MyFMT, MyPathRoot);
- HR_(StringCchLengthW(MyPathRoot, NTFS_MAX_PATH, &MyPathRoot_Len), 1003)
- // ---> For debug
- printf("RelativePath=\t%100S\n", LeadingLibraryRelativePath);
- const WCHAR* pFullPath = ToFullPath(MyPathRoot, LeadingLibraryRelativePath);
- if (PathFileExistsW(pFullPath))
- printf(" FullPath= \t%100S\n", pFullPath);
- else printf("file not exist\t%100S\n", LeadingLibraryRelativePath);
- // ---> For debug
- PAUSE
- return 0;
- }
- int My_Console_Main(const wchar_t* comment) {
- int rv;
- printf("%S\n", comment);
- printf("CommandLine=%S\n", GetCommandLineW());
- if (AppInitialize())return -1;
- try {
- MyFileForDebug = new FileForDebug();
- //HR_(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE), 1)
- //HR_(OleInitialize(NULL), 2)
- if (rv = Get_CreationInstance_To_Create_FollowingServer(
- ToFullPath(MyPathRoot, LeadingLibraryRelativePath),
- LeadingLibrary_clsid, LeadingLibrary_IID))return rv;
- if (rv = My_Test_Function_dotNET())return rv;
- printf("http://cheninnjer.blogspot.com\n");
- system("pause");
- Get_CreationInstance_To_Create_UnregisteredServer(
- CreationInstance_clsid, CreationInstance_iid);
- if (rv = My_Test_Function())return rv;
- system("pause");
- MyEnumModules();
- system("pause");
- ReleaseResource_dotNET();
- ReleaseResource();
- system("pause");
- //OleUninitialize();
- //CoUninitialize();
- MyFileForDebug->Save();
- }
- 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;
- }
- int Get_CreationInstance_To_Create_FollowingServer(
- LPCOLESTR LeadingLibrary_AbsolutePath,
- LPCOLESTR CLSID_String, LPCOLESTR IID_String) {
- HRESULT CreateLeadingLibrary(
- const wchar_t* LeadingLibrary_FullPath,
- const wchar_t* param_LeadingLibrary_clsid, void** ppvoid);
- HR_(CreateLeadingLibrary(LeadingLibrary_AbsolutePath,
- CLSID_String, (void**)&pIUnknown_dotNET), 12)
- IID MyIID;
- HR_(IIDFromString(AddCurlyBracket(IID_String), &MyIID), 13)
- HR_(pIUnknown_dotNET->QueryInterface(MyIID, (void**)&pICreationInstance_dotNET), 14)
- if (pIUnknown_dotNET + 1 != pICreationInstance_dotNET)
- ErrorMessage("pIUnknown_dotNET + 1 != pICreationInstance_dotNET");
- BSTR Description = NULL;
- HR_(pICreationInstance_dotNET->GetDescription2(&Description), 17)
- MyWriteLine(L"%s", Description);
- ::SysFreeString(Description);
- return 0;
- }
- void Get_CreationInstance_To_Create_UnregisteredServer(
- LPCOLESTR CLSID_String, LPCOLESTR IID_String) {
- HRESULT hr;
- 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);
- }
- int My_Test_Function_dotNET() {
- int length = ARRAYSIZE(ClientInfo_dotNET);
- for (int aa = 0; aa < length; aa++) {
- HMODULE& hModule = ClientInfo_dotNET[aa].hModule;
- const WCHAR* DLL_Absolute_Path = ToFullPath(MyPathRoot, ClientInfo_dotNET[aa].DLL_Path);
- hModule = ClientInfo_dotNET[aa].MFC_DLL ?
- AfxLoadLibrary(DLL_Absolute_Path) : LoadLibraryW(DLL_Absolute_Path);
- if (!hModule) {
- printf("Error: %S\n", DLL_Absolute_Path);
- RETURN(21)
- }
- using Test_UnregisteredServer = int (*)(TestParameter*);
- Test_UnregisteredServer FunctionPointer =
- (Test_UnregisteredServer)GetProcAddress(hModule, ClientInfo_dotNET[aa].ProcName);
- if (!FunctionPointer) {
- if (b_FreeLibrary) {
- ClientInfo_dotNET[aa].MFC_DLL ?
- AfxFreeLibrary(hModule) : FreeLibrary(hModule);
- hModule = NULL;
- }
- RETURN(22)
- }
- TestParameter MyParameter = {
- Debug_namespace::My_Write_Line,
- pICreationInstance_dotNET ,
- MyPathRoot
- };
- int rv = FunctionPointer(&MyParameter);
- if (b_FreeLibrary) {
- ClientInfo_dotNET[aa].MFC_DLL ?
- AfxFreeLibrary(hModule) : FreeLibrary(hModule);
- hModule = NULL;
- }
- if (rv)RETURN(rv)
- }
- return 0;
- }
- int My_Test_Function() {
- int length = ARRAYSIZE(ClientInfo);
- for (int aa = 0; aa < length; aa++) {
- HMODULE& hModule = ClientInfo[aa].hModule;
- 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) {
- printf("Error: %S\n", DLL_Absolute_Path);
- RETURN(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);
- hModule = NULL;
- }
- RETURN(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);
- hModule = NULL;
- }
- if (rv)RETURN(rv);
- }
- return 0;
- }
- void ReleaseResource_dotNET() {
- if (!pIUnknown_dotNET || !pICreationInstance_dotNET)return;
- HRESULT hr;
- IDispatch* pIDispatch_dotNET;
- hr = pIUnknown_dotNET->QueryInterface(IID_IDispatch, (void**)&pIDispatch_dotNET);
- if (FAILED(hr))
- ErrorMessage("QueryInterface (IID_IDispatch) ");
- else
- printf(" %p(%d)pIDispatch_dotNET\n", pIDispatch_dotNET, pIDispatch_dotNET->Release());
- printf(" %p(%d)pIUnknown_dotNET\n", pIUnknown_dotNET, pIUnknown_dotNET->Release());
- printf(" %p(%d)pICreationInstance_dotNET\n", pICreationInstance_dotNET,
- pICreationInstance_dotNET->Release());
- }
- void ReleaseResource() {
- if (!pIUnknown || !pICreationInstance)return;
- HRESULT hr;
- 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);
- 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);
- 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
- using namespace System;
- namespace CreatedotNETPlatform {
- public ref class Class1
- {
- // TODO: Add your methods for this class here.
- void MyInspection(void);
- String^ LeadingLibPath;
- Reflection::Assembly^ Assembly_Leading_Library;
- Type^ clsid_type;
- public:
- long Create_dotNET_Platform(
- const wchar_t* LeadingLib,
- const wchar_t* clsid,
- void** pIUnknown);
- };
- }
- #include "pch.h"
- #include "TestParameter.h"
- #include "Create_dotNET_Platform.h"
- __declspec(dllexport) HRESULT CreateLeadingLibrary(
- const wchar_t* LeadingLibPath,
- const wchar_t* clsid_Str,
- void** pIUnknown)
- {
- long errorCode = (
- gcnew CreatedotNETPlatform::Class1()
- )->Create_dotNET_Platform(LeadingLibPath, clsid_Str, pIUnknown);
- if (errorCode)return (HRESULT)(errorCode + (7 << 29));
- return S_OK;
- }
- using namespace System::Reflection;
- using namespace System::Runtime::InteropServices;
- namespace CreatedotNETPlatform {
- long Class1::Create_dotNET_Platform(
- const wchar_t* Leading_Library_Path,
- const wchar_t* clsid_str,
- void** pIunknown)
- {
- size_t String_Len;
- try {
- //throw gcnew System::FormatException("MyTest");
- if (FAILED(StringCchLengthW(Leading_Library_Path, 4000, &String_Len))) return 1;
- LeadingLibPath = gcnew String(Leading_Library_Path, 0, (int)String_Len);
- Assembly_Leading_Library = Reflection::Assembly::LoadFrom(LeadingLibPath);
- if (FAILED(StringCchLengthW(clsid_str, 200, &String_Len))) return 2;
- Guid clsid = Guid::Parse(gcnew String(clsid_str, 0, (int)String_Len));
- Collections::Generic::IEnumerable<Type^>^ IEnumateType =
- Assembly_Leading_Library->ExportedTypes;
- for each (clsid_type in IEnumateType)
- if (clsid_type->GUID == clsid) {
- MyInspection();
- Object^ obj = Activator::CreateInstance(clsid_type);
- if (obj) {
- *pIunknown = Marshal::GetIUnknownForObject(obj).ToPointer();
- return 0;
- }
- else return 0X9;
- }
- return 0xb;
- }
- catch (System::IO::FileNotFoundException^ const f) {
- System::String^ des = L" FileNotFound ->" + f->FileName;
- System::IntPtr ptr = Marshal::StringToHGlobalUni(des);
- SetErrorInfo_Chen((const WCHAR*)ptr.ToInt64(), __FUNCTIONW__);
- Marshal::FreeHGlobal(ptr);
- return 0x100;
- }
- catch (System::Exception^ const ex) {
- System::String^ des = L" Exception Message ->" + ex->Message;
- System::IntPtr ptr = Marshal::StringToHGlobalUni(des);
- SetErrorInfo_Chen((const WCHAR*)ptr.ToInt64(), __FUNCTIONW__);
- Marshal::FreeHGlobal(ptr);
- return 0x333;
- }
- }
- void Class1::MyInspection(void) {
- MethodInfo^ Get_Interface3;
- array<ParameterInfo^>^ MyParams;
- //throw gcnew Exception("My Exception");
- Console::WriteLine("*************************");
- Console::WriteLine("__cplusplus_cli = " + __cplusplus_cli);
- Console::WriteLine(__func__);
- Console::WriteLine(" __FUNCSIG__ = " __FUNCSIG__);
- Console::WriteLine(
- "FrameworkDescription is " +
- Runtime::InteropServices::RuntimeInformation::FrameworkDescription
- );
- Console::WriteLine("Leading Library path = " + LeadingLibPath);
- if (!clsid_type)goto out;
- Console::WriteLine("CLSID = " + clsid_type->GUID);
- Console::WriteLine("FullName = " + clsid_type->FullName);
- Get_Interface3 = clsid_type->GetMethod("Get_Interface3");
- if (!Get_Interface3) goto out;
- Console::WriteLine("Get_Interface3");
- MyParams = Get_Interface3->GetParameters();
- for each (ParameterInfo ^ MyParam in MyParams) {
- Console::WriteLine("Position:" + MyParam->Position.ToString() +
- " TypeName(" + MyParam->ParameterType->Name + ")");
- }
- out:
- Console::WriteLine("*************************");
- Console::ReadKey();
- }
- }
- #If TARGET = "library" And PLATFORM = "x64" Then
- Option Strict On
- Imports System.Reflection
- Imports System.Runtime.InteropServices
- Imports System.Text
- <ComClass(LeadingLibrary.ClassId, LeadingLibrary.IID_LeadingLibrary)>
- Public Class LeadingLibrary
- Public Const ClassId As String = "2B6E5DB5-CF45-40B8-8091-55027E408231"
- Public Const IID_LeadingLibrary As String = "16142434-D1CF-4DC8-BD7B-7E5091058490"
- Sub Get_Interface3(<[In]> AssemblyInfo_ptr As IntPtr,
- <Out> ByRef ppVoid As IntPtr)
- 'Throw New MyException(&HE0000004, "Don't use Get_Interface3")
- 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
- Throw New MyException(ex.HResult, AssemblyPath & " Cannot be found")
- Catch ex As Exception
- Throw New MyException(ex.HResult, "Unknown Exception -->" & ex.Message)
- End Try
- If ppVoid = IntPtr.Zero Then
- Throw New MyException(&HE0000222, "ppVoid = ZERO")
- End If
- End Sub
- Sub GetDescription(Description As IntPtr)
- Dim Source As New StringBuilder(
- "This is a leadingLibrary")
- 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(LeadingLibrary)
- 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(LeadingLibrary)
- Dim ThisModule As Reflection.Module = MainType.Module
- Dim peKind As PortableExecutableKinds
- Dim machine As ImageFileMachine
- ThisModule.GetPEKind(peKind, machine)
- Dim Source As New StringBuilder()
- Source.AppendLine("This is a LeadingLibrary")
- 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)
- Source.Append($"machine={machine} peKind={peKind}")
- Description = Source.ToString()
- End Sub
- Sub Get_Interface4(<[In]> AssemblyInfo_ptr As IntPtr,
- <Out> ByRef ppVoid_object As Object)
- Try
- MyAssemblyInfo =
- Marshal.PtrToStructure(Of AssemblyInfo_Struct)(AssemblyInfo_ptr)
- AssemblyPath =
- Marshal.PtrToStringBSTR(MyAssemblyInfo.AssemblyPath)
- UnregisteredServerAssembly = Assembly.LoadFrom(AssemblyPath)
- InvokeCreationMethod4()
- ppVoid_object = ppvoid_temp_object
- Catch ex As IO.FileNotFoundException
- Throw New MyException(ex.HResult, AssemblyPath & " Cannot be found")
- Catch ex As Exception
- Throw New MyException(ex.HResult, "Unknown Exception -->" & ex.Message)
- End Try
- If ppVoid_object Is Nothing Then
- Throw New MyException(&HE0000222, "ppVoid_object Is Nothing")
- End If
- 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
- Private 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 ppvoid_temp_object As Object
- 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 MyTypeInfo As TypeInfo In IEnumateType
- If Type_CLSID <> MyTypeInfo.GUID Then Continue For
- TypeFullname = Marshal.PtrToStringBSTR(MyAssemblyInfo.TypeFullname)
- If TypeFullname <> MyTypeInfo.FullName Then
- Dim FG As ConsoleColor = Console.ForegroundColor
- Console.ForegroundColor = ConsoleColor.Green
- Console.WriteLine("In :" & TypeFullname)
- Console.WriteLine("MyType :" & MyTypeInfo.FullName)
- Console.ForegroundColor = FG
- End If
- Dim UnregisteredServerType As Type = MyTypeInfo.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 args() As Object = {Interface_IID, ppvoid_temp, New IntPtr(12345)}
- CreateObject_Chen.Invoke(Nothing, args)
- Exit Sub
- Next
- Throw New Exception("Error:CLSID not found")
- End Sub
- Private Sub InvokeCreationMethod4()
- ' Console.WriteLine("InvokeCreationMethod4()")
- 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 MyTypeInfo As TypeInfo In IEnumateType
- If Type_CLSID <> MyTypeInfo.GUID Then Continue For
- TypeFullname = Marshal.PtrToStringBSTR(MyAssemblyInfo.TypeFullname)
- If TypeFullname <> MyTypeInfo.FullName Then
- Dim FG As ConsoleColor = Console.ForegroundColor
- Console.ForegroundColor = ConsoleColor.Green
- Console.WriteLine("In :" & TypeFullname)
- Console.WriteLine("MyType :" & MyTypeInfo.FullName)
- Console.ForegroundColor = FG
- End If
- Dim UnregisteredServerType As Type = MyTypeInfo.AsType
- CreationMethod = Marshal.PtrToStringBSTR(MyAssemblyInfo.CreationMethod)
- Dim CreateObject4_Chen As MethodInfo =
- UnregisteredServerType.GetMethod(CreationMethod)
- If CreateObject4_Chen Is Nothing Then
- Throw New Exception($"Err:CreateObject4_Chen Is Nothing({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 args() As Object = {Interface_IID, New IntPtr(12345)}
- ppvoid_temp_object = CreateObject4_Chen.Invoke(Nothing, args)
- Exit Sub
- Next MyTypeInfo
- Throw New Exception("Error:CLSID not found")
- End Sub
- End Class
- #End If
- #include "pch.h"
- #if defined(_M_X64) && defined(_WIN64) && defined(_WINDOWS) && \
- _MSVC_LANG >= 202002L && defined(_USRDLL)
- #include "TestParameter.h"
- LPCOLESTR MyServerName = Server_Name_w(
- CSharp_Server_For_Testing\CSharp_Server_For_Testing\bin\x64\,
- My_Configuration, \net9.0\CSharp_Server_For_Testing.dll);
- __interface IMyTest : IDispatch {
- HRESULT Hello(INT32 id, BSTR str);
- };
- __interface IMyTest2 : IDispatch {
- HRESULT Hello2(BSTR* str);
- HRESULT Test_in_out_ref(
- INT32* ref_int32,
- INT32 int32_2,
- INT32* out_int32,
- void* ptr);
- HRESULT Test_ref_readonly(INT32* ref_int32, void* ptr);
- };
- __interface IMyTest3 : IDispatch {
- HRESULT Hello3(BSTR* str);
- };
- HRESULT pfnDeferredFillIn(EXCEPINFO* pEx) {
- for (int aa = 1; aa < 20; aa++) printf("Description\n");
- PAUSE
- //printf("Description=%S\n", pEx->bstrDescription);
- return S_OK;
- }
- int Invoke_Hello_method(ExportedData& ED, IMyTest* pIMyTest) {
- CComBSTR str = SysAllocString(L"=========== Hello method ==========");
- HRESULT hr;
- auto Invoke_Hello = [&](int ID) {
- hr = pIMyTest->Hello(ID, str);
- ED.WriteLine(L"hr = 0X%X", hr);
- CComPtr<IErrorInfo> MypError;
- hr = GetErrorInfo(0, &MypError);
- if (SUCCEEDED(hr)) {
- CComBSTR Description, source;
- MypError->GetDescription(&Description);
- MypError->GetSource(&source);
- ED.WriteLine(L"Description=%s", Description);
- ED.WriteLine(L"Source=%s", source);
- }
- };
- Invoke_Hello(1);
- Invoke_Hello(222);
- DISPID dispid_Hello;
- LPCOLESTR names = L"Hello";
- HR_(pIMyTest->GetIDsOfNames(IID_NULL, const_cast<LPOLESTR*>(&names), 1,
- LOCALE_USER_DEFAULT, &dispid_Hello), -1234)
- ED.WriteLine(L"========== DISPID=%d ===========\n", dispid_Hello);
- for (int ID = 111; ID <= 222; ID += 111) {
- VARIANTARG varg[2], pRetValue;
- UINT puArgErr = 0;
- DISPPARAMS DispParams{
- .rgvarg = varg,
- .rgdispidNamedArgs = new DISPID[]{ },
- .cArgs = 2,
- .cNamedArgs = 0,
- };
- VariantInit(varg);
- V_VT(varg) = VT_BSTR; V_BSTR(varg) = str; //in reverse order
- VariantInit(varg + 1);
- V_VT(varg + 1) = VT_I4; V_I4(varg + 1) = ID;
- VariantInit(&pRetValue);
- V_VT(&pRetValue) = VT_I4;
- EXCEPINFO ex = {
- .pfnDeferredFillIn = pfnDeferredFillIn,
- .scode = (LONG)0XE0012345
- };
- hr = pIMyTest->Invoke(dispid_Hello,
- IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
- &DispParams, &pRetValue, &ex, &puArgErr);
- printf("puArgErr=%d MyHRESULT=0x%x\n", puArgErr, hr);
- if (V_VT(&pRetValue) != VT_EMPTY)
- printf(" type=%d RetValue=0x%x\n", V_VT(&pRetValue), V_I4(&pRetValue));
- if (hr == DISP_E_EXCEPTION) {
- printf("ex.wCode=%d ex.scode=0X%X \n", ex.wCode, ex.scode);
- printf("ex.bstrSource: %S \n", ex.bstrSource);
- hr = ex.scode;
- }
- ED.WriteLine(L"hr = 0X%X", hr);
- }
- return 0;
- }
- class MyEventTestClass :public IDispatch
- {
- LONG refCount;
- public:
- MyEventTestClass() : refCount(0) {}
- HRESULT QueryInterface(REFIID iid, void** ppvoid) {
- printf("QueryInterface\n");
- LPOLESTR iid_str;
- HR_(StringFromIID(iid, &iid_str), -1212)
- printf("IID=%S\n", iid_str);
- CoTaskMemFree(iid_str);
- PAUSE
- if (iid == IID_IUnknown) {
- printf(" IID_IUnknown\n");
- *ppvoid = dynamic_cast<IUnknown*>(this);
- refCount++;
- return S_OK;
- }
- if (iid == IID_INoMarshal) {
- printf(" IID_INoMarshal\n");
- return E_NOINTERFACE;
- }
- if (iid == IID_IAgileObject) {
- printf(" IID_IAgileObject\n");
- return E_NOINTERFACE;
- }
- if (iid == IID_IMarshal) {
- printf(" IID_IMarshal\n");
- return E_NOINTERFACE;
- }
- printf(" QueryInterface error\n");
- return S_FALSE;
- }
- ULONG AddRef() {
- refCount++;
- printf("AddRef(%d) \n", refCount);
- PAUSE
- return refCount;
- }
- ULONG Release() {
- refCount--;
- printf("Release(%d) \n", refCount);
- PAUSE
- return refCount;
- }
- HRESULT GetTypeInfoCount(UINT* pctInfo) {
- printf("GetTypeInfoCount\n");
- PAUSE
- if (!pctInfo)return E_POINTER;
- ITypeInfo* pITypeInfo;
- //TYPEINfoHelp
- *pctInfo = 0;
- return S_FALSE;
- }
- HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) {
- printf("GetTypeInfo\n");
- PAUSE
- return 0;
- }
- HRESULT GetIDsOfNames(REFIID iid, LPOLESTR* str,
- UINT cNames, LCID lcid, DISPID* rgDispID) {
- printf("GetIDsOfNames\n");
- PAUSE
- return S_OK;
- }
- HRESULT Invoke(DISPID dispidMember, REFIID iid, LCID lcid, WORD flag,
- DISPPARAMS* dispParam,
- VARIANT* pVariant, EXCEPINFO* pExcepInfo, UINT* puArg) {
- printf("Invoke\n");
- PAUSE
- return 0;
- }
- };
- __interface IClass1Events : IDispatch {};
- static int Test_Event(IMyTest* pIMyTest) {
- HRESULT hr;
- LPCOLESTR IDD_Event = (LPCOLESTR)OLESTR("3AAEFAB5-6DC7-49FD-A658-44A8DEF91F02");
- IClass1Events* pIClass1Events = NULL;
- IID myiid2;
- HR_(IIDFromString(AddCurlyBracket(IDD_Event), &myiid2), -32)
- HR_(pIMyTest->QueryInterface(myiid2, (void**)&pIClass1Events), -33)
- printf("------------ Event -------------\n");
- DISPID DispID_add_MyTestFun;
- LPCOLESTR names = L"add_Event_MyTestFun";
- HR_(pIClass1Events->GetIDsOfNames(IID_NULL, (LPOLESTR*)&names, 1,
- LOCALE_USER_DEFAULT, &DispID_add_MyTestFun), -333)
- printf("DispID_add_MyTestFun = 0X%X\n", DispID_add_MyTestFun);
- VARIANTARG varg[2], pRetValue;
- DISPPARAMS DispParams{};
- DispParams.cArgs = 1;
- DispParams.rgvarg = varg;
- VariantInit(varg);
- std::unique_ptr<MyEventTestClass> pkkk(new MyEventTestClass);
- V_VT(varg) = VT_UNKNOWN;
- V_UNKNOWN(varg) = static_cast<IUnknown*>(pkkk.get());
- V_UNKNOWN(varg) = NULL;
- VariantInit(&pRetValue);
- UINT puArgErr = 0;
- EXCEPINFO ex{};
- hr = pIClass1Events->Invoke(DispID_add_MyTestFun,
- IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD,
- &DispParams, &pRetValue, &ex, &puArgErr);
- if (FAILED(hr))
- if (DISP_E_TYPEMISMATCH == hr) printf("Type mismatch\n");
- else if (E_INVALIDARG == hr) printf("One or more arguments are invalid\n");
- else if (DISP_E_BADPARAMCOUNT == hr) printf("Invalid number of parameter\n");
- else {
- printf("pRetValue=0X%X\n", V_I4(&pRetValue));
- printf("hr=0X%X puArgErr=%d\n", hr, puArgErr);
- }
- printf("------------ Event -------------(%d)\n", pIClass1Events->Release());
- return 0;
- }
- struct My_Struct {
- INT32 A;
- INT32 B;
- INT32 C;
- };
- extern "C" __declspec(dllexport)
- int CPP_DLL_Test_CSharp_Server(TestParameter* ptr) {
- ExportedData ED(ptr, L"DLL_Test_CSharp_Server");
- int rv;
- IMyTest* pIMyTest;
- ServerInfo_Struct<LPCOLESTR> My_Server_string = {
- MyServerName,
- (LPCOLESTR)OLESTR("CSharp_Server_For_Testing.Class1"),
- (LPCOLESTR)OLESTR("CreateObject4_Chen"),
- (LPCOLESTR)OLESTR("6E0C1B45-7569-47DA-AE26-4BE21F323923"),
- (LPCOLESTR)OLESTR("FECA0AEE-FF0F-4897-8CB9-27B44BB97765")
- };
- rv = Get_ServerInterface4(ptr, My_Server_string, (PVOID*)&pIMyTest);
- if (rv)return rv;
- if (Invoke_Hello_method(ED, pIMyTest))return -1000;
- if (Test_Event(pIMyTest))return -10001;
- printf("(%d)pIMyTest->Release %p\n", pIMyTest->Release(), pIMyTest);
- PAUSE
- IMyTest2* pIMyTest2 = NULL;
- My_Server_string.IID = (LPCOLESTR)OLESTR("C8439959-322C-4FE3-AC66-24B062A77152");
- rv = Get_ServerInterface4(ptr, My_Server_string, (PVOID*)&pIMyTest2);
- if (rv)return rv;
- CComBSTR str2 = NULL;
- HR_(pIMyTest2->Hello2(&str2), -3456)
- ED.WriteLine(L"str2(%s)", str2);
- INT32 ref_int32, out_int32;
- My_Struct s{ 11,2,3 };
- pIMyTest2->Test_in_out_ref(&ref_int32, 34, &out_int32, (void*)&s);
- ED.WriteLine(L"ref_int32 = %d out_int32=%d", ref_int32, out_int32);
- pIMyTest2->Test_ref_readonly(&ref_int32, (void*)&s);
- ED.WriteLine(L"ref_readonly_int32 = %d %d", ref_int32, s.A);
- printf("(%d)pIMyTest2->Release %p\n", pIMyTest2->Release(), pIMyTest2);
- PAUSE
- IMyTest3* pIMyTest3 = NULL;
- My_Server_string.IID = (LPCOLESTR)OLESTR("731D1161-8436-4827-AB75-F334A112B2F1");
- rv = Get_ServerInterface4(ptr, My_Server_string, (PVOID*)&pIMyTest3);
- if (rv)return rv;
- printf("(pIMyTest3 = %p)\n", pIMyTest3);
- str2.Empty();
- HR_(pIMyTest3->Hello3(&str2), -34563)
- ED.WriteLine(L"str2(%s)", str2);
- ED.WriteLine(L"(%d)pIMyTest3->Release ", pIMyTest3->Release());
- PAUSE
- return 0;
- }
- #endif
- using System.Runtime.InteropServices;
- namespace CSharp_Server_For_Testing
- {
- [Guid(Class1.IMyTest_IID)]
- [ComVisible(true)]
- public interface IMyTest
- {
- [DispId(8)] void Hello(Int32 id, String str);
- }
- [Guid(clsid)]
- [ClassInterface(ClassInterfaceType.None)]
- public partial class Class1 : IMyTest
- {
- public const String clsid = "6E0C1B45-7569-47DA-AE26-4BE21F323923";
- public const String IMyTest_IID = "FECA0AEE-FF0F-4897-8CB9-27B44BB97765";
- void IMyTest.Hello(Int32 id, String str)
- {
- Console.WriteLine(str + $" id = {id}");
- EventHandler_MyTestFun?.Invoke(this, EventArgs.Empty);
- Console.WriteLine("************** Hello world *****************");
- if (id == 111) return;
- else if (id == 222) System.Reflection.Assembly.LoadFrom("");
- else throw new Exception() { HResult = (0XE << 28) | 0X12345 };
- }
- public static object? CreateObject4_Chen(ref Guid IID, IntPtr Not_Used)
- {
- if (IID == Guid.Parse(Class1.IMyTest_IID))
- {
- return new Class1();
- }
- Object? MyReturnObj = null;
- Console.WriteLine($"{IID} ------Enter MyMethod_Next_Interface2");
- MyMethod_Next_Interface2(in IID, ref MyReturnObj);
- Console.WriteLine($"{IID} ------Exit MyMethod_Next_Interface2");
- Console.ReadKey();
- if (MyReturnObj != null) return MyReturnObj;
- return null;
- }
- static partial void MyMethod_Next_Interface2(in Guid IID, ref object? MyReturnObj);
- }
- }
- using System.Runtime.InteropServices;
- namespace CSharp_Server_For_Testing
- {
- public struct MyStruct
- {
- public Int32 A;
- public Int32 B;
- public Int32 C;
- };
- [Guid(Class1.IMyTest2_IID)]
- [ComVisible(true)]
- public interface IMyTest2
- {
- [DispId(0x33)] void Hello2(ref String str);
- [DispId(0x34)]
- void
- Test_in_out_ref(ref Int32 ref_int32,
- Int32 int32_2,
- out Int32 out_int32,
- in MyStruct s);
- [DispId(0x35)]
- void Test_readonly_ref(ref readonly Int32 ref_int32,
- ref readonly MyStruct s);
- }
- public partial class Class1 : IMyTest2
- {
- public const String IMyTest2_IID = "C8439959-322C-4FE3-AC66-24B062A77152";
- void IMyTest2.Hello2(ref String str)
- {
- Console.WriteLine("************** Hello world -2 *****************");
- str = $"=== void IMyTest2.Hello2(ref String str) === <<-- ";
- }
- void IMyTest2.Test_in_out_ref(ref Int32 ref_int32, Int32 int32_2,
- out Int32 out_int32, in MyStruct s)
- {
- ref_int32 = 10000 + int32_2;
- out_int32 = 1110000;
- out_int32 += s.A;
- Console.WriteLine($"out_int32 = {out_int32}");
- }
- void IMyTest2.Test_readonly_ref(ref readonly Int32 ref_readonly_int32,
- ref readonly MyStruct s)
- {
- Console.WriteLine($"ref_readonly_int32 = {ref_readonly_int32}");
- Console.WriteLine($"ref_readonly s.A= {s.A}");
- }
- static partial void MyMethod_Next_Interface2(in Guid IID, ref object? MyReturnObj)
- {
- if (IID == Guid.Parse(Class1.IMyTest2_IID))
- {
- Console.WriteLine($"{IID} MyMethod_Next_Interface2");
- Console.ReadKey();
- MyReturnObj = new Class1();
- }
- else
- {
- Console.WriteLine($"{IID} ------Enter MyMethod_Next_Interface3");
- MyMethod_Next_Interface3(in IID, ref MyReturnObj);
- Console.WriteLine($"{IID} ------Exit MyMethod_Next_Interface3");
- }
- }
- static partial void MyMethod_Next_Interface3(in Guid IID, ref object? MyReturnObj);
- }
- }
- using System.Runtime.InteropServices;
- namespace CSharp_Server_For_Testing
- {
- [Guid(Class1.IMyTest3_IID)]
- [ComVisible(true)]
- public interface IMyTest3
- {
- [DispId(333)] void Hello3(ref String str);
- }
- public partial class Class1 : IMyTest3
- {
- public const String IMyTest3_IID = "731D1161-8436-4827-AB75-F334A112B2F1";
- void IMyTest3.Hello3(ref String str)
- {
- Console.WriteLine("=======************** Hello world -3 *****************");
- GC.Collect();
- GC.WaitForPendingFinalizers();
- str = $"=== void IMyTest3.Hello3(ref String str) ===";
- }
- void Destructor()
- {
- Console.WriteLine();
- Console.WriteLine("~Class1() Destructor() -------------");
- Console.Beep();
- Console.WriteLine("------------- ~Class1() Destructor() ");
- }
- ~Class1()
- {
- Destructor();
- }
- static Class1 MyClass1_obj = new Class1();
- static partial void MyMethod_Next_Interface3(in Guid IID, ref object? MyReturnObj)
- {
- if (IID == Guid.Parse(Class1.IMyTest3_IID))
- {
- Console.WriteLine($"{IID} MyMethod_Next_Interface3");
- MyReturnObj = MyClass1_obj;
- Console.WriteLine(" MyReturnObj = new Class1();");
- Console.ReadKey();
- }
- else
- {
- Console.WriteLine($"{IID} ------Enter MyMethod_Next_Interface4");
- MyMethod_Next_Interface4(in IID, ref MyReturnObj);
- Console.WriteLine($"{IID} ------Exit MyMethod_Next_Interface4");
- }
- }
- static partial void MyMethod_Next_Interface4(in Guid IID, ref object? MyReturnObj);
- }
- }
- using System.Runtime.InteropServices;
- namespace CSharp_Server_For_Testing
- {
- [Guid(Class1.IMyTest_Event_IID)]
- [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
- [ComVisible(true)]
- public interface IClass1Events
- {
- event EventHandler Event_MyTestFun;
- }
- [ComSourceInterfaces(typeof(IClass1Events))]
- [ProgId("MyTest_Chen.ProgId")]
- public partial class Class1 : IClass1Events
- {
- public const String IMyTest_Event_IID = "3AAEFAB5-6DC7-49FD-A658-44A8DEF91F02";
- private event EventHandler? EventHandler_MyTestFun;
- public event EventHandler? Event_MyTestFun
- {
- add
- {
- Console.WriteLine($" add MyTestFun {value?.GetType().FullName}");
- Console.WriteLine($" value is null = {value is null}");
- Console.ReadKey();
- if (value is not null) EventHandler_MyTestFun += value;
- }
- remove
- {
- Console.WriteLine("remove MyTestFun ");
- Console.ReadKey();
- if (value is not null) EventHandler_MyTestFun -= value;
- }
- }
- }
- }
- #include "pch.h"
- #if defined(_M_X64) && defined(_WIN64) && defined(_WINDOWS) && \
- _MSVC_LANG >= 202002L && defined(_USRDLL)
- #include "TestParameter.h"
- LPCOLESTR MyServerName = (LPCOLESTR)Server_Name_w(MultiInface_VB_NET\MultiInface_VB_NET\bin\x64\,
- My_Configuration, \net9.0\MultiInface_VB_NET.dll);
- struct Microsoft_Example_Struct;
- typedef INT32(*VB_Fun_Type)(LPSTR* str, LPWSTR* wstr);
- typedef HRESULT(*CPP_Fun_Type)(PWSTR lpString, int nMaxCount);
- typedef void (*std_fun_ptr)(void);
- __interface _MultiInterface : IDispatch {
- HRESULT Array_in(BSTR* result, SAFEARRAY* long_64_bit, SAFEARRAY* pDouble);
- HRESULT Array_In_Out(BSTR str, double* Double1, SAFEARRAY** DoubleArrary, SAFEARRAY** Lock);
- HRESULT Property_Get_Array(BSTR str, SAFEARRAY** pRetVal);
- HRESULT ArraysWithinStructures(Microsoft_Example_Struct P1, Microsoft_Example_Struct* P2);
- };
- __interface IMyTest2 : IDispatch {
- HRESULT Map_HRESULTs_and_Exceptions_1(long ID);
- HRESULT Map_HRESULTs_and_Exceptions_2(long ID);
- };
- __interface IMyTest3 : IDispatch {
- HRESULT TestFunctionPointer(CPP_Fun_Type CPP_Func, VB_Fun_Type* VB_Func);
- HRESULT Test_Delegate(std_fun_ptr CPP_Func);
- };
- class SafeArrayPtr {
- SAFEARRAY* ptr;
- public:
- SafeArrayPtr(VARTYPE vt, UINT cDim, ULONG cElement1, ULONG cElement2 = 0) {
- SAFEARRAYBOUND SafeArrayBound[2] = { {cElement1,0},{cElement2,0} };
- ptr = SafeArrayCreate(vt, cDim, SafeArrayBound);
- if (!ptr)throw "SafeArrayCreate";
- }
- ~SafeArrayPtr() {
- SafeArrayDestroy(ptr);
- ptr = NULL;
- }
- ULONG CountOfElement(int Dim) { return ptr->rgsabound[Dim].cElements; }
- SAFEARRAY* operator->() { return ptr; }
- SafeArrayPtr& operator =(SAFEARRAY* ptr) { this->ptr = ptr; return *this; }
- SAFEARRAY** operator&() { return &ptr; }
- operator SAFEARRAY* () { return ptr; }
- };
- void MultiInterface_Array_in(ExportedData& ED, _MultiInterface* p_MultiInterface) {
- HRESULT hr;
- const int Count_Of_dim1 = 12;
- SafeArrayPtr pSafeArray_Double(VT_R8, 1, Count_Of_dim1);
- SafeArrayPtr pSafeArray_LongLong(VT_I8, 1, Count_Of_dim1);
- double* pdouble = NULL;
- long long* ptr_LongLong = NULL;
- if (SUCCEEDED(SafeArrayAccessData(pSafeArray_Double, (void**)&pdouble)) &&
- SUCCEEDED(SafeArrayAccessData(pSafeArray_LongLong, (void**)&ptr_LongLong)))
- {
- for (int ii = 0; ii < pSafeArray_Double.CountOfElement(0); ii++) {
- pdouble[ii] = ii * 10 + 5;
- ptr_LongLong[ii] = 100 * ii + 7;
- }
- SafeArrayUnaccessData(pSafeArray_Double);
- SafeArrayUnaccessData(pSafeArray_LongLong);
- BSTR str = NULL;
- hr = p_MultiInterface->Array_in(&str, pSafeArray_LongLong, pSafeArray_Double);
- if (SUCCEEDED(hr)) ED.WriteLine(L"%s", str);
- //if (SUCCEEDED(hr)) printf("%S",str);
- else ED.WriteLine(L"error: p_MultiInterface->Array_in hr=%X", hr);
- ::SysFreeString(str);
- }
- }
- void MultiInterface_Array_In_Out(ExportedData& ED, _MultiInterface* p_MultiInterface) {
- HRESULT hr;
- SafeArrayPtr pSafeArray_In_Out_Lock(VT_R8, 1, 500000);
- SAFEARRAY* pSafeArray_In_Out_Lock_Original = pSafeArray_In_Out_Lock;
- SafeArrayLock(pSafeArray_In_Out_Lock);
- double* pDouble_in_Lock, * pDouble_out_Lock;
- SafeArrayAccessData(pSafeArray_In_Out_Lock, (void**)&pDouble_in_Lock);
- SafeArrayUnaccessData(pSafeArray_In_Out_Lock);
- //--------------------------------------------------
- SafeArrayPtr pMy_SafeArray(VT_R8, 1, 500);
- double* pDouble_in, * pDouble_out;
- double Double1 = 123.456789;
- SafeArrayAccessData(pMy_SafeArray, (void**)&pDouble_in);
- pDouble_in[1] = 111.111;
- SafeArrayUnaccessData(pMy_SafeArray);
- BSTR str2 = SysAllocString(L"MultiInterface_Array_In_Out");
- hr = p_MultiInterface->Array_In_Out(str2, &Double1, &pMy_SafeArray, &pSafeArray_In_Out_Lock);
- ::SysFreeString(str2);
- if (SUCCEEDED(hr)) {
- wprintf(L"Double1 = %f\n", Double1);
- SafeArrayAccessData(pMy_SafeArray, (void**)&pDouble_out);
- wprintf(L"pDouble2[1] = %f\n", pDouble_out[1]);
- wprintf(L"pDouble2[33] = %f\n", pDouble_out[33]);
- SafeArrayUnaccessData(pMy_SafeArray);
- if (pDouble_in != pDouble_out) {
- wprintf(L"pDouble_in (%p)\n", pDouble_in);
- wprintf(L"pDouble_out (%p)\n", pDouble_out);
- }
- //-------------------------------------------------
- SafeArrayAccessData(pSafeArray_In_Out_Lock, (void**)&pDouble_out_Lock);
- wprintf(L"pDouble_out_Lock[22] (%f)\n", pDouble_out_Lock[22]);
- SafeArrayUnaccessData(pSafeArray_In_Out_Lock);
- if (pDouble_in_Lock != pDouble_out_Lock) {
- wprintf(L"pDouble_in_Lock != pDouble_out_Lock\n");
- }
- if (pSafeArray_In_Out_Lock != pSafeArray_In_Out_Lock_Original) {
- wprintf(L"pSafeArray_In_Out_Lock != pSafeArray_In_Out_Lock_Original\n");
- SafeArrayDestroy(pSafeArray_In_Out_Lock);
- pSafeArray_In_Out_Lock = pSafeArray_In_Out_Lock_Original;
- }
- }
- SafeArrayUnlock(pSafeArray_In_Out_Lock);
- }
- void MultiInterface_Property_Get_Array(ExportedData& ED, _MultiInterface* p_MultiInterface) {
- HRESULT hr;
- SAFEARRAY* pSafeArray = NULL;
- BSTR str2 = SysAllocString(L"MultiInterface_Property_Get_Array");
- hr = p_MultiInterface->Property_Get_Array(str2, &pSafeArray);
- ::SysFreeString(str2);
- if (SUCCEEDED(hr)) {
- double* pDouble;
- SafeArrayLock(pSafeArray);
- hr = SafeArrayAccessData(pSafeArray, (void**)&pDouble);
- if (SUCCEEDED(hr)) {
- LONG LowerBound;
- SafeArrayGetLBound(pSafeArray, 1, &LowerBound);
- LONG UpperBound;
- SafeArrayGetUBound(pSafeArray, 1, &UpperBound);
- for (int aa = LowerBound; aa <= UpperBound; aa++) {
- ED.WriteLine(L"Property_Get_Array pDouble(%d) = %f", aa, pDouble[aa]);
- }
- SafeArrayUnaccessData(pSafeArray);
- }
- SafeArrayUnlock(pSafeArray);
- SafeArrayDestroy(pSafeArray);
- }
- }
- struct Microsoft_Example_Struct {
- short s1[128];
- WCHAR* f1;
- WCHAR f2[256];
- BSTR f3;
- };
- void MultiInterface_ArraysWithinStructures(ExportedData& ED, _MultiInterface* p_MultiInterface) {
- HRESULT hr;
- WCHAR* f_1 = const_cast<WCHAR*>(L"ABCDEF");
- BSTR f_3 = ::SysAllocString(L"CPP_f3");
- Microsoft_Example_Struct P1{ {},f_1,L"CPP_f2",f_3 }, P2{ {},NULL,{},NULL };
- P1.s1[10] = 4444;
- P2.s1[10] = 5555;
- hr = p_MultiInterface->ArraysWithinStructures(P1, &P2);
- ::SysFreeString(f_3);
- if (SUCCEEDED(hr)) {
- ED.WriteLine(L"P1.s1[10]=%d", P1.s1[10]);
- ED.WriteLine(L"P2.s1[10]=%d", P2.s1[10]);
- PAUSE
- }
- }
- void IMyTest2_Map_HRESULTs_and_Exceptions_1(ExportedData& ED, IMyTest2* pIMyTest2) {
- for (int id = 0X234; id < 0X238; id++)
- {
- HRESULT hr;
- hr = pIMyTest2->Map_HRESULTs_and_Exceptions_1(id);
- if (FAILED(hr)) {
- ED.WriteLine(L"hr=%X", hr);
- IErrorInfo* pError;
- hr = GetErrorInfo(0, &pError);
- if (SUCCEEDED(hr)) {
- BSTR Description, source;
- pError->GetDescription(&Description);
- pError->GetSource(&source);
- ED.WriteLine(L"Description=%s", Description);
- ED.WriteLine(L"Source=%s", source);
- SysFreeString(Description); SysFreeString(source);
- pError->Release();
- }
- }
- }
- }
- void IMyTest2_Map_HRESULTs_and_Exceptions_2(ExportedData& ED, IMyTest2* pIMyTest2) {
- for (int ID = 1; ID <= 5; ID++) {
- HRESULT hr;
- hr = pIMyTest2->Map_HRESULTs_and_Exceptions_2(ID);
- if (FAILED(hr)) ED.WriteLine(L"hr=%X", hr);
- hr = [=]()->HRESULT {
- HR_(pIMyTest2->Map_HRESULTs_and_Exceptions_2(ID), 334455)
- return S_OK;
- }();
- ED.WriteLine(L"rerurnValue=%d", hr);
- }
- PAUSE
- }
- HRESULT Fixed_length_string_buffer(PWSTR lpString, int nMaxCount) {
- printf("\nCPP_Function\n");
- StringCchCopyW(lpString, nMaxCount, L"Fixed_length_string_buffer");
- return S_OK;
- }
- void IMyTest3_TestFunctionPointer(ExportedData& ED, IMyTest3* pIMyTest3) {
- VB_Fun_Type VB_Fun;
- HRESULT hr;
- hr = pIMyTest3->TestFunctionPointer(Fixed_length_string_buffer, &VB_Fun);
- if (FAILED(hr)) ED.WriteLine(L"Error: hr=%X in IMyTest3_TestFunctionPointer", hr);
- INT32 retVal;
- for (int64_t aa = 0; aa < 3; aa++) {
- LPSTR str = NULL;
- LPWSTR wstr = NULL;
- retVal = VB_Fun(&str, &wstr);
- printf("(%s) retVal=%d\n", str, retVal);
- printf("(%S)\n", wstr);
- }
- }
- void IMyTest3_Test_Delegate(ExportedData& ED, IMyTest3* pIMyTest3) {
- HRESULT hr;
- hr = pIMyTest3->Test_Delegate((std_fun_ptr)Fixed_length_string_buffer);
- if (FAILED(hr)) ED.WriteLine(L" ->hr=%X in IMyTest3_Test_Delegate", hr);
- }
- #define LOOP1(xx) for(int64_t aaa =0 ; aaa < xx ; aaa++)
- extern "C"
- int CPP_DLL_Test_MultiInterface(TestParameter* ptr) {
- ExportedData ED(ptr, L"CPP_DLL_Test_MultiInterface");
- int rv = 0;
- try
- {
- IMyTest3* pIMyTest3;
- _MultiInterface* p_MultiInterface;
- IMyTest2* pIMyTest2;
- [&]() {
- ServerInfo_Struct<LPCOLESTR> My_Server_string = {
- MyServerName,
- (LPCOLESTR)OLESTR("MultiInface_VB_NET.MultiInterface"),
- (LPCOLESTR)OLESTR("CreateObject4_Chen"),
- (LPCOLESTR)OLESTR("77381cf4-badb-4ee7-b51f-9090fe145c39"),
- (LPCOLESTR)OLESTR("636B8701-78D1-482C-9A2A-E7259C23AEB5")
- };
- rv = Get_ServerInterface4(ptr, My_Server_string, (PVOID*)&p_MultiInterface);
- if (rv)throw std::exception("Get_ServerInterface", rv);
- LOOP1(2) MultiInterface_Array_in(ED, p_MultiInterface);
- //PAUSE
- LOOP1(2) MultiInterface_Array_In_Out(ED, p_MultiInterface);
- //PAUSE
- MultiInterface_Property_Get_Array(ED, p_MultiInterface);
- MultiInterface_ArraysWithinStructures(ED, p_MultiInterface);
- }();
- [&]() {
- ServerInfo_Struct<LPCOLESTR> My_Server_string = {
- MyServerName,
- (LPCOLESTR)OLESTR("MultiInface_VB_NET.MultiInterface"),
- (LPCOLESTR)OLESTR("CreateObject4_Chen"),
- (LPCOLESTR)OLESTR("77381cf4-badb-4ee7-b51f-9090fe145c39"),
- (LPCOLESTR)OLESTR("31D53FF8-4768-4A77-95E3-DC28DEBB375F")
- };
- rv = Get_ServerInterface4(ptr, My_Server_string, (PVOID*)&pIMyTest2);
- if (rv)throw std::exception("Get_ServerInterface", rv);
- IMyTest2_Map_HRESULTs_and_Exceptions_1(ED, pIMyTest2);
- IMyTest2_Map_HRESULTs_and_Exceptions_2(ED, pIMyTest2);
- }();
- [&]() {
- ServerInfo_Struct<LPCOLESTR> My_Server_string = {
- MyServerName,
- (LPCOLESTR)OLESTR("MultiInface_VB_NET.MultiInterface"),
- (LPCOLESTR)OLESTR("CreateObject4_Chen"),
- (LPCOLESTR)OLESTR("77381cf4-badb-4ee7-b51f-9090fe145c39"),
- (LPCOLESTR)OLESTR("9E7F18F8-3B02-4AE0-89A9-DD35240BF509")
- };
- rv = Get_ServerInterface4(ptr, My_Server_string, (PVOID*)&pIMyTest3);
- if (rv)throw std::exception("Get_ServerInterface", rv);
- IMyTest3_TestFunctionPointer(ED, pIMyTest3);
- IMyTest3_Test_Delegate(ED, pIMyTest3);
- //PAUSE
- }();
- wprintf(L"%p(%d)p_MultiInterface\n", p_MultiInterface, p_MultiInterface->Release());
- wprintf(L"%p(%d)pIMyTest2 \n", pIMyTest2, pIMyTest2->Release());
- wprintf(L"%p(%d)pIMyTest3 \n", pIMyTest3, pIMyTest3->Release());
- PAUSE
- }
- catch (const std::exception& ex)
- {
- printf("exception:(%s) in multi-Interface \n", ex.what());
- }
- return rv;
- }
- #endif
- LIBRARY
- EXPORTS
- CPP_DLL_Test_MultiInterface @1
- Imports System.Buffers
- Imports System.Reflection
- Imports System.Runtime.InteropServices
- Imports System.Runtime.InteropServices.Marshalling
- Imports System.Text
- <ComClass(MultiInterface.MultiInterface_CLSID, MultiInterface.I_MultiInterface_IID, MultiInterface.EventsId)>
- Public Class MultiInterface : Implements IMyTest2, IMyTest3
- #Region "COM GUIDs"
- ' These GUIDs provide the COM identity for this class
- ' and its COM interfaces. If you change them, existing
- ' clients will no longer be able to access the class.
- Public Const MultiInterface_CLSID As String = "77381cf4-badb-4ee7-b51f-9090fe145c39"
- Public Const I_MultiInterface_IID As String = "636b8701-78d1-482c-9a2a-e7259c23aeb5"
- Public Const IMyTest2_IID As String = "31D53FF8-4768-4A77-95E3-DC28DEBB375F"
- Public Const IMyTest3_IID As String = "9E7F18F8-3B02-4AE0-89A9-DD35240BF509"
- Public Const EventsId As String = "c340a1eb-b81b-4553-bc5c-db85fdd3cfc0"
- #End Region
- Public Sub New()
- MyBase.New()
- MyStringBuilder = New StringBuilder()
- End Sub
- Dim MyStringBuilder As StringBuilder
- Sub Array_in(<Out> ByRef str As String, <[In]> long_64_bit As Long(),
- <[In]> pDouble As Double())
- MyStringBuilder.Clear()
- MyStringBuilder.AppendLine("Array_in *** IN")
- MyStringBuilder.AppendLine($"LowerBound= {pDouble.GetLowerBound(0)} UpperBound={pDouble.GetUpperBound(0)}")
- For ii As Int32 = pDouble.GetLowerBound(0) To pDouble.GetUpperBound(0)
- MyStringBuilder.AppendLine($"{ii:d2}: {pDouble(ii):F2}{vbTab} {long_64_bit(ii)}")
- Next
- MyStringBuilder.AppendLine("Array_in *** OUT")
- str = MyStringBuilder.ToString()
- End Sub
- Sub Array_In_Out(<[In]> str As String,
- <[In], Out> ByRef Double1 As Double,
- <[In], Out> ByRef DoubleArray_inOut As Double(),
- <[In], Out> ByRef DoubleArray_In_Out_Lock As Double()
- )
- Dim Len As Integer = DoubleArray_inOut.GetLength(0)
- Console.WriteLine(str)
- Console.WriteLine($"Length of DoubleArray = {Len} --- .NET")
- Console.WriteLine($"Double1 = {Double1} -- .NET")
- Console.WriteLine($"DoubleArray(1) ={DoubleArray_inOut(1)} --- .NET")
- Double1 = 987.654321
- DoubleArray_inOut(33) = 33.33
- DoubleArray_In_Out_Lock(22) = 22.22
- End Sub
- Dim _DoubleArray(8) As Double
- ReadOnly Property Property_Get_Array(<[In]> str As String) _
- As <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_R8)> Double()
- Get
- Console.WriteLine(str)
- Dim Len As Integer = _DoubleArray.GetLength(0)
- Console.WriteLine($"Property_Get_Array --- Length = {Len}")
- For aa As Integer = _DoubleArray.GetLowerBound(0) To _DoubleArray.GetUpperBound(0)
- _DoubleArray(aa) = aa * 200 + 7
- Next
- Return _DoubleArray
- End Get
- End Property
- Sub ArraysWithinStructures(<[In]> P1 As Microsoft_Example_Struct,
- <[In], Out> ByRef P2 As Microsoft_Example_Struct)
- Console.WriteLine($"P1.f1={P1.f1} -- .NET")
- Console.WriteLine($"P1.f2={P1.f2} -- .NET")
- Console.WriteLine($"P1.f3={P1.f3} -- .NET")
- If P1.f2 <> "CPP_f2" Then
- Throw New Exception("P1.f2 <> CPP_f2")
- End If
- Console.WriteLine($"P1.s1(10)={P1.s1(10)} -- .NET")
- Console.WriteLine($"P2.s1(10)={P2.s1(10)} -- .NET")
- P1.s1(10) = -987
- P2.s1(10) = 1010
- Console.ReadKey()
- End Sub
- '================ IMyTest2 =======================
- Private Sub Map_HRESULTs_and_Exceptions_1(ID As Int32) Implements IMyTest2.Map_HRESULTs_and_Exceptions_1
- Dim ApplicationException As New ApplicationException("My description in MyTest1")
- ApplicationException.HResult = (7 << 29) Or ID
- ApplicationException.Source = "MyTest1"
- Console.WriteLine($"hr={ApplicationException.HResult:X} -- MyTest1")
- Throw ApplicationException
- End Sub
- Private Sub Map_HRESULTs_and_Exceptions_2(ID As Int32) Implements IMyTest2.Map_HRESULTs_and_Exceptions_2
- Select Case ID
- Case 1
- Try
- Assembly.LoadFrom("")
- Catch ex As Exception
- Dim What_is_this As New ArgumentException
- Console.WriteLine(
- $"hr={ex.HResult:X} == {What_is_this.HResult:X} {What_is_this}")
- End Try
- Assembly.LoadFrom("")
- Case 2
- Dim _INT64 As Int64
- Try
- _INT64 = 2 / (ID - 2)
- Catch ex As Exception
- Dim What_is_this As New OverflowException
- Console.WriteLine(
- $"hr={ex.HResult:X} == {What_is_this.HResult:X} {What_is_this}")
- End Try
- _INT64 = 2 / (ID - 2)
- Case 5
- Case Else
- Dim MyException As New Exception With {
- .HResult = (7 << 29) Or ID}
- Throw MyException
- End Select
- End Sub
- Protected Delegate Function MyFunction_CPP(<Out> lpString() As Char, nMaxCount As Integer) As Int32
- Protected Delegate Function MyFunction_VB(<[In], Out> ByRef str As String,
- <[In], Out, MarshalAs(UnmanagedType.LPWStr)> ByRef wstr As String) As Int32
- Shared Function VB_Func1(<[In], Out> ByRef str As String,
- <[In], Out, MarshalAs(UnmanagedType.LPWStr)> ByRef wstr As String) As Int32
- str = "Shared Function VB_Func1(<[In], Out> ByRef str As String,....) As Int32"
- wstr = "Shared Function VB_Func1(..., <[In], Out, MarshalAs(UnmanagedType.LPWStr)> ByRef wstr As String) As Int32"
- Return 34567
- End Function
- '================ IMyTest2 =======================
- '================ IMyTest3 =======================
- Private Sub TestFunctionPointer(<[In]> CPP_FuncPtr As IntPtr,
- <[In], Out> ByRef VB_Func As IntPtr
- ) Implements IMyTest3.TestFunctionPointer
- Dim temp_Delegate As [Delegate] = [Delegate].CreateDelegate(GetType(MyFunction_VB),
- GetType(MultiInterface).GetMethod("VB_Func1"))
- VB_Func = Marshal.GetFunctionPointerForDelegate(Of MyFunction_VB)(
- CType(temp_Delegate, MyFunction_VB))
- '---------------
- Dim CPP_Func As MyFunction_CPP =
- Marshal.GetDelegateForFunctionPointer(Of MyFunction_CPP)(CPP_FuncPtr)
- Const Length As Int32 = 256
- Dim buffer() As Char = ArrayPool(Of Char).Shared.Rent(Length)
- Dim hResult As Int32 = CPP_Func.Invoke(buffer, Length)
- Dim str As New String(buffer)
- Console.WriteLine($"hResult={hResult} {str}")
- ArrayPool(Of Char).Shared.Return(buffer)
- 'Console.ReadKey()
- End Sub
- Private Sub Test_Delegate(<[In]> CPP_FuncPtr As IntPtr) Implements IMyTest3.Test_Delegate
- Dim hResult As Int32
- Const Length As Int32 = 256
- Dim buffer() As Char = ArrayPool(Of Char).Shared.Rent(Length)
- Dim ParamList As Object() = {buffer, Length}
- Dim CPP_Func As MyFunction_CPP
- Try
- CPP_Func = Marshal.GetDelegateForFunctionPointer(Of MyFunction_CPP)(CPP_FuncPtr)
- hResult = CPP_Func.DynamicInvoke(ParamList)
- Catch ex As Exception
- Console.WriteLine($"Error: {ex.Message} ")
- Console.ReadKey()
- End Try
- Console.WriteLine($"Test_Delegate ---hResult={hResult} {New String(buffer)}")
- ArrayPool(Of Char).Shared.Return(buffer)
- End Sub
- '================ IMyTest3 =======================
- Shared MyMultiInterface_Object As MultiInterface
- Shared Function CreateObject4_Chen(ByRef IID As Guid,
- Not_Used As IntPtr) As Object
- If MyMultiInterface_Object Is Nothing Then
- MyMultiInterface_Object = New MultiInterface
- End If
- Dim MyIID As Guid = Guid.Parse(I_MultiInterface_IID)
- Dim MyIID2 As Guid = Guid.Parse(IMyTest2_IID)
- Dim MyIID3 As Guid = Guid.Parse(IMyTest3_IID)
- If MyIID = IID OrElse MyIID2 = IID OrElse MyIID3 = IID Then
- 'Console.WriteLine("CreateObject4_Chen ---Object")
- Return MyMultiInterface_Object
- End If
- 'Console.WriteLine("CreateObject4_Chen Nothing")
- Return Nothing
- End Function
- End Class
- <Guid(MultiInterface.IMyTest3_IID)>
- Public Interface IMyTest3
- Sub TestFunctionPointer(<[In]> MyFunc As IntPtr, <[In], Out> ByRef VB_Func As IntPtr)
- Sub Test_Delegate(<[In]> MyFunc As IntPtr)
- End Interface
- <Guid(MultiInterface.IMyTest2_IID)>
- Public Interface IMyTest2
- Sub Map_HRESULTs_and_Exceptions_1(ID As Int32)
- Sub Map_HRESULTs_and_Exceptions_2(ID As Int32)
- End Interface
- <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
- Public Structure Microsoft_Example_Struct
- <MarshalAs(UnmanagedType.ByValArray, SizeConst:=128)> Public s1() As Int16
- <MarshalAs(UnmanagedType.LPWStr)> Public f1 As String
- <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public f2 As String
- <MarshalAs(UnmanagedType.BStr)> Public f3 As String
- End Structure
- Public Structure RetValue4
- Public ppvoid As Object
- End Structure
- <GeneratedComInterface>
- <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
- Interface IMyTest_1
- Sub MyTest1(ID As Int32)
- Sub MyTest2(ID As Int32)
- End Interface
- <GeneratedComInterface>
- <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
- Interface IMyTest_2 : Inherits IMyTest_1
- Sub MyTest3(<[In]> MyFunc As IntPtr)
- End Interface
- ' If you do not have a type library for an interface
- ' you can redeclare it using ComImportAttribute.
- ' This is how the interface would look in an idl file.
- '[
- 'object,
- 'uuid("73EB4AF8-BE9C-4b49-B3A4-24F4FF657B26"),
- 'dual, helpstring("IMyStorage Interface"),
- 'pointer_default(unique)
- ']
- 'interface IMyStorage : IDispatch
- '{
- ' [id(1)]
- ' HRESULT GetItem([in] BSTR bstrName, [out, retval] IDispatch ** ppItem);
- ' [id(2)]
- ' HRESULT GetItems([in] BSTR bstrLocation, [out] SAFEARRAY(VARIANT)* pItems);
- ' [id(3)]
- ' HRESULT GetItemDescriptions([in] BSTR bstrLocation, [out] SAFEARRAY(VARIANT) ** ppItems);
- ' [id(4), propget]
- ' HRESULT get_IsEmpty([out, retval] BOOL * pfEmpty);
- '};
- ' This is the managed declaration.
- <ComImport(), Guid("73EB4AF8-BE9C-4b49-B3A4-24F4FF657B26")>
- Public Interface IMyStorage
- <DispId(1)>
- Function GetItem(<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByVal bstrName As String) _
- As <MarshalAs(UnmanagedType.Interface)> Object
- <DispId(2)>
- Function GetItems(<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByVal bstrLocation As String,
- <OutAttribute(), MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VarEnum.VT_VARIANT)>
- ByVal Items() As Object)
- <DispId(3)>
- Function GetItemDescriptions(<InAttribute()> ByVal bstrLocation As String,
- <InAttribute(), OutAttribute(),
- MarshalAs(UnmanagedType.SafeArray)> ByRef varDescriptions() As Object)
- <DispId(4)>
- ReadOnly Property IsEmpty(<MarshalAs(UnmanagedType.VariantBool)> ByVal bEmpty As Boolean)
- End Interface
- LIBRARY
- EXPORTS
- CPP_DLL_Test_UnregisteredServer1 @1
- CPP_DLL_Test_UnregisteredServer2 @2
- CPP_DLL_Test_IXXXX @3
- #include "pch.h"
- #if defined(_M_X64) && defined(_WIN64) && defined(_WINDOWS) && \
- _MSVC_LANG >= 202002L && defined(_USRDLL)
- #include "TestParameter.h"
- extern "C" /* exported functions */ {
- int CPP_DLL_Test_UnregisteredServer1(TestParameter*);
- int CPP_DLL_Test_UnregisteredServer2(TestParameter*);
- int CPP_DLL_Test_IXXXX(TestParameter*);
- }
- LPCOLESTR MyServerName = Server_Name_w(dotNET_ClassLibrary\dotNET_ClassLibrary\bin\x64\,
- My_Configuration, \net9.0\dotNET_ClassLibrary.dll);
- ServerInfo_Struct<LPCOLESTR> My_Server_string[] = {
- {
- MyServerName,
- (LPCOLESTR)OLESTR("DotNet_ClassLibrary.MyUnregisterServer1"),
- (LPCOLESTR)OLESTR("CreateObject4_Chen"),
- (LPCOLESTR)OLESTR("04D9F530-CE0C-4232-8F3F-6E0A3244C715"),
- (LPCOLESTR)OLESTR("31D53FF8-4768-4A77-95E3-DC28DEBB375F")
- },{
- MyServerName,
- (LPCOLESTR)OLESTR("DotNet_ClassLibrary.MyUnregisterServer2"),
- (LPCOLESTR)OLESTR("CreateObject3_Chen"),
- (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
- (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
- },{
- MyServerName,
- (LPCOLESTR)OLESTR("DotNet_ClassLibrary.MyUnregisterServer2"),
- (LPCOLESTR)OLESTR("CreateObject4_Chen"),
- (LPCOLESTR)OLESTR("7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"),
- (LPCOLESTR)OLESTR("FDD5D79A-386E-49D0-AF60-81222A990055")
- }
- };
- /* 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) {
- HRESULT hr;
- ExportedData ED(ptr, L"Test_UnregisteredServer1 CPP_DLL");
- IUnregisteredServer1* pIUnregisteredServer1 = NULL;
- int rv = Get_ServerInterface4(ptr, My_Server_string[0], (PVOID*)&pIUnregisteredServer1);
- if (rv)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);
- int errorCode = 0;
- IUnknown* ptr_IUnknown1 = NULL;
- IUnknown* ptr_IUnknown2 = NULL;
- IUnknown* ptr_IUnknown3 = NULL;
- IDispatch* ptr_IDispatch = NULL;
- hr = pIUnregisteredServer1->Get_Interface((PVOID*)&ptr_IUnknown1);
- if (FAILED(hr)) {
- ED.WriteLine(L"error: pIUnregisteredServer1->Get_Interface hr=%X", hr);
- }
- VARIANT _variant;
- VariantInit(&_variant);
- hr = pIUnregisteredServer1->Get_Interface2(2, &_variant);
- if (FAILED(hr)) {
- ED.WriteLine(L"error: pIUnregisteredServer1->Get_Interface2 hr=%X", hr);
- }
- if (V_VT(&_variant) == VT_UNKNOWN) {
- ptr_IUnknown2 = V_UNKNOWN(&_variant);
- if (ptr_IUnknown2 != ptr_IUnknown1) errorCode = 1;
- }
- else if (V_VT(&_variant) == VT_DISPATCH) {
- ptr_IDispatch = V_DISPATCH(&_variant);
- if (ptr_IUnknown1 + 1 != ptr_IDispatch) errorCode = 2;
- }
- else errorCode = 3;
- if (errorCode) {
- pIUnregisteredServer1->QueryInterface(IID_IUnknown, (void**)&ptr_IUnknown3);
- printf(" ptr_IUnknown3=%p\n", ptr_IUnknown3);
- printf(" ptr_IUnknown2=%p\n", ptr_IUnknown2);
- printf(" ptr_IUnknown1=%p\n", ptr_IUnknown1);
- printf(" ptr_IDispatch=%p\n", ptr_IDispatch);
- printf(" pIUnregisteredServer1=%p\n", pIUnregisteredServer1);
- ED.WriteLine(
- L"error: V_VT(&_variant)=%d VT_DISPATCH:%d VT_UNKNOWN=%d errorCode=%d",
- V_VT(&_variant), VT_DISPATCH, VT_UNKNOWN, errorCode
- );
- }
- 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) {
- HRESULT hr;
- ExportedData ED(ptr, L"Test_UnregisteredServer2 CPP_DLL");
- IUnregisteredServer2_CPP* pIUnregisteredServer2_CPP;
- int rv = Get_ServerInterface(ptr, My_Server_string[1], (PVOID*)&pIUnregisteredServer2_CPP);
- if (rv)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"Test_IXXXX CPP_DLL");
- IXXXX* pIXXXX;
- int rv = Get_ServerInterface4(ptr, My_Server_string[2], (PVOID*)&pIXXXX);
- if (rv)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
- #If TARGET = "library" And PLATFORM = "x64" Then
- Option Strict On
- Imports System.Runtime.InteropServices
- <ComClass(MyUnregisterServer1.ClassId, MyUnregisterServer1.InterfaceId)>
- Public Class MyUnregisterServer1
- Public Const ClassId As String = "04D9F530-CE0C-4232-8F3F-6E0A3244C715"
- Public Const InterfaceId As String = "31D53FF8-4768-4A77-95E3-DC28DEBB375F"
- ReadOnly Property Get_Interface() As <MarshalAs(UnmanagedType.IUnknown)> Object
- Get
- MyTrace("Get_Interface")
- Return CreateObject_Chen()
- End Get
- End Property
- Sub Get_Interface2(Interface_ID As Int32,
- <Out> ByRef ppVoid As Object)
- 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)
- CppEventClassObj.Register_Event(FunctionPointer, BSTR_String, ID)
- MyTrace($"Register_Event {ID}")
- End Sub
- Sub RemoveEvent(<[In]> ID As Int32)
- MyTrace($"RemoveEvent {ID}")
- CppEventClassObj.RemoveEvent(ID)
- End Sub
- Sub Raise_Event(MyTestParameter As Int64)
- MyTrace($"Raise_Event {MyTestParameter}")
- CppEventClassObj.RaiseEventParameter = MyTestParameter
- RaiseEvent Cpp_Event(Me, CppEventClassObj)
- End Sub
- Dim _MyProperty As Int32 = 222
- Property MyProperty As Int32
- 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
- ReadOnly Property TraceMessage As String
- Get
- TraceMessage = Environment.NewLine &
- "==== TraceMessage(Chen Inn-Jer) ======" &
- Environment.NewLine & _TraceMessage.ToString() &
- "==== TraceMessage(Chen Inn-Jer) ======" &
- Environment.NewLine
- _TraceMessage.Clear() : TraceSteps = 0
- End Get
- End Property
- '1----------------------------------------------------
- Private Class CppEventClass : Inherits EventArgs
- Public RaiseEventParameter As Int64
- Private EventCount As Int32
- Private Delegate Sub DelegateForFunctionPointer(
- ByRef obj As System.Object)
- Private 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
- Private 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" &
- Environment.NewLine & MyItem.InputString)
- End If
- Next
- End Sub
- End Class
- Private ReadOnly CppEventClassObj As CppEventClass
- Private Event Cpp_Event As EventHandler
- Shared Function CreateObject_Chen() As MyUnregisterServer1
- If MyUnregisterServer1_Object Is Nothing Then
- MyUnregisterServer1_Object = New MyUnregisterServer1
- End If
- Return MyUnregisterServer1_Object
- End Function
- Shared MyUnregisterServer1_Object As MyUnregisterServer1
- 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}")
- Dim ppVoid As IntPtr
- Dim MyIID As Guid = Guid.Parse(InterfaceId)
- If MyIID = IID Then
- ppVoid = Marshal.GetIUnknownForObject(MyUnregisterServer1_Object)
- Else
- ppVoid = IntPtr.Zero
- End If
- Marshal.WriteIntPtr(ppvoid_temp, ppVoid)
- End Sub
- Shared Function CreateObject4_Chen(ByRef IID As Guid,
- Not_Used As IntPtr) As Object
- If MyUnregisterServer1_Object Is Nothing Then
- MyUnregisterServer1_Object = New MyUnregisterServer1()
- End If
- MyUnregisterServer1_Object.MyTrace(
- $"MyUnregisterServer1 IID={IID} Not_Used = {Not_Used}")
- Dim MyIID As Guid = Guid.Parse(InterfaceId)
- If MyIID = IID Then
- 'Console.WriteLine("CreateObject4_Chen ---Object")
- Return MyUnregisterServer1_Object
- End If
- 'Console.WriteLine("CreateObject4_Chen Nothing")
- Return Nothing
- End Function
- Sub New()
- MyBase.New()
- CppEventClassObj = New CppEventClass(Me)
- _TraceMessage = New Text.StringBuilder
- 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 TraceSteps As Int32
- Private ReadOnly _TraceMessage As Text.StringBuilder
- Private Sub MyTrace(msg As String)
- TraceSteps += 1
- _TraceMessage.AppendLine($"{TraceSteps:d2} : {msg}")
- End Sub
- End Class
- '1 ================================================== 2
- <ComClass(MyUnregisterServer2.ClassId, MyUnregisterServer2.InterfaceId)>
- Public Class MyUnregisterServer2
- Public Const ClassId As String = "7FDF74B5-2E5D-4B72-B3A3-5BA424645F0D"
- Public Const InterfaceId As String = "FDD5D79A-386E-49D0-AF60-81222A990055"
- Sub DefaultMarshallingForObject(ByRef obj As Object,
- ByRef obj2 As Object,
- ByRef obj3 As Object
- )
- MyTrace($"({obj})DefaultMarshallingForObject-->&H999L")
- obj = &H999L
- 'obj2 = New System.Decimal(666666)
- obj2 = 666.6666
- End Sub
- Sub Map_HResultAndException(
- <Out, MarshalAs(UnmanagedType.BStr)>
- ByRef Display As String
- )
- 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
- Sub Hello_world3(
- decimal2 As System.Decimal,
- guid As System.Guid,
- <Out, MarshalAs(UnmanagedType.BStr)> ByRef outputResult As String
- )
- 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)
- End Sub
- Sub AddRef2()
- End Sub
- Sub Release2()
- End Sub
- Sub GetTypeInfoCount2(
- <Out> ByRef out_UINT_pctinfo As UInt32)
- End Sub
- Sub GetTypeInfo2(
- itinfo As UInt32, lcid As UInt32,
- <Out, MarshalAs(UnmanagedType.Interface)> ByRef ppTInfo As Object
- )
- 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)
- 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)
- End Sub
- ReadOnly Property TraceMessage As String
- Get
- TraceMessage = Environment.NewLine &
- "==== TraceMessage(Chen Inn-Jer) 2 ======" &
- Environment.NewLine & _TraceMessage.ToString() &
- "==== TraceMessage(Chen Inn-Jer) 2 ======" &
- Environment.NewLine
- _TraceMessage.Clear() : TraceSteps = 0
- End Get
- End Property
- Sub YYYY(<Out> ByRef intptr_obj As IntPtr)
- intptr_obj = New IntPtr(12345678)
- MyTrace($"YYYY({intptr_obj})")
- End Sub
- Sub YYYY1(<[In], Out, MarshalAs(UnmanagedType.BStr)> ByRef Comment As String)
- 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" &
- Environment.NewLine & "MyLocation is " &
- Reflection.Assembly.GetExecutingAssembly.Location &
- Environment.NewLine & "FrameworkDescription is " &
- Runtime.InteropServices.RuntimeInformation.FrameworkDescription &
- Environment.NewLine & $"machine={machine} peKind={peKind}" &
- Environment.NewLine
- End Sub
- '2------------------------------------------------
- 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}")
- Dim ppvoid As IntPtr
- Dim MyIID As Guid = Guid.Parse(InterfaceId)
- If MyIID = IID Then
- ppvoid = Marshal.GetIUnknownForObject(MyUnregisterServer2_Object)
- Else
- ppvoid = IntPtr.Zero
- End If
- Marshal.WriteIntPtr(ppvoid_temp, ppvoid)
- End Sub
- Shared Function CreateObject4_Chen(ByRef IID As Guid,
- Not_Used As IntPtr) As Object
- If MyUnregisterServer2_Object Is Nothing Then
- MyUnregisterServer2_Object = New MyUnregisterServer2()
- End If
- MyUnregisterServer2_Object.MyTrace(
- $"MyUnregisterServer2 IID={IID} Not_Used = {Not_Used}")
- Dim MyIID As Guid = Guid.Parse(InterfaceId)
- If MyIID = IID Then
- 'Console.WriteLine("CreateObject4_Chen ---Object")
- Return MyUnregisterServer2_Object
- End If
- 'Console.WriteLine("CreateObject4_Chen Nothing")
- Return Nothing
- End Function
- 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
- Dim TraceSteps As Int32
- Dim _TraceMessage As Text.StringBuilder
- Private Sub MyTrace(msg As String)
- TraceSteps += 1
- _TraceMessage.AppendLine($"{TraceSteps:d2} : {msg}")
- End Sub
- End Class
- #End If




































































































































































































































留言
張貼留言