mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
211 lines
4.7 KiB
C++
211 lines
4.7 KiB
C++
// ==++==
|
|
//
|
|
//
|
|
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
|
|
//
|
|
// The use and distribution terms for this software are contained in the file
|
|
// named license.txt, which can be found in the root of this distribution.
|
|
// By using this software in any fashion, you are agreeing to be bound by the
|
|
// terms of this license.
|
|
//
|
|
// You must not remove this notice, or any other, from this software.
|
|
//
|
|
//
|
|
// ==--==
|
|
// ===========================================================================
|
|
// File: nativedll.cpp
|
|
//
|
|
// native dll for FFI testing, can be reused for other tests too
|
|
// ===========================================================================
|
|
|
|
#include "windows.h"
|
|
#include "stdlib.h"
|
|
|
|
#include "cor.h"
|
|
#include "corffi.h"
|
|
|
|
extern "C" BOOL WINAPI DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID pvReserved )
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
if (PAL_Initialize(NULL, NULL) != 0)
|
|
return FALSE;
|
|
DisableThreadLibraryCalls(hInst);
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
PAL_Terminate();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void fail(char *msg)
|
|
{
|
|
fprintf(stderr, "Failed: %s\n", msg);
|
|
exit(1);
|
|
}
|
|
|
|
// simple delegate roundtrip
|
|
typedef int (__stdcall *MySimpleDelegate)(int x);
|
|
|
|
MySimpleDelegate g_CachedSimpleDelegate;
|
|
|
|
extern "C" void __stdcall CacheSimpleDelegate(MySimpleDelegate pfn)
|
|
{
|
|
g_CachedSimpleDelegate = pfn;
|
|
}
|
|
|
|
extern "C" int __stdcall CallSimpleDelegate(MySimpleDelegate pfn, int x)
|
|
{
|
|
if (pfn == NULL)
|
|
pfn = g_CachedSimpleDelegate;
|
|
|
|
return pfn(x) + 1;
|
|
}
|
|
|
|
// delegate roundtrip
|
|
typedef double (__stdcall *MyDelegate)(IUnknown* punk);
|
|
|
|
MyDelegate g_CachedDelegate;
|
|
|
|
extern "C" void __stdcall CacheDelegate(MyDelegate pfn)
|
|
{
|
|
g_CachedDelegate = pfn;
|
|
}
|
|
|
|
extern "C" double __stdcall CallDelegate(MyDelegate pfn, IUnknown* punk)
|
|
{
|
|
if (pfn == NULL)
|
|
pfn = g_CachedDelegate;
|
|
|
|
return pfn(punk) + 1;
|
|
}
|
|
|
|
// ffi roundtrip
|
|
extern "C" double __stdcall CallFFI(IUnknown* pcallback, IUnknown* punk)
|
|
{
|
|
IManagedInstanceWrapper* pmiw;
|
|
VARIANT arg;
|
|
VARIANT retval;
|
|
HRESULT hr;
|
|
|
|
V_VT(&arg) = VT_UNKNOWN;
|
|
V_UNKNOWN(&arg) = punk;
|
|
|
|
pcallback->QueryInterface(IID_IManagedInstanceWrapper, (void**)&pmiw);
|
|
hr = pmiw->InvokeByName(
|
|
L"MyCallback", CorFFIInvokeMethod, 1, &arg, &retval);
|
|
pmiw->Release();
|
|
|
|
if (FAILED(hr))
|
|
fail("MyCallback failed");
|
|
|
|
if (V_VT(&retval) != VT_R8)
|
|
fail("Expected R8");
|
|
|
|
return V_R8(&retval) + 1;
|
|
}
|
|
|
|
// array marshalling
|
|
extern "C" int __stdcall Sum(int count, int* a)
|
|
{
|
|
int sum = 0;
|
|
for (int i = 0; i < count; i++)
|
|
sum += a[i];
|
|
return sum;
|
|
}
|
|
|
|
// array marshalling ex
|
|
extern "C" int __stdcall ObjectSum(int count, IUnknown** a)
|
|
{
|
|
int sum = 0;
|
|
for (int i = 0; i < count; i++) {
|
|
VARIANT var;
|
|
HRESULT hr;
|
|
IManagedInstanceWrapper* pmiw;
|
|
|
|
a[i]->QueryInterface(IID_IManagedInstanceWrapper, (void**)&pmiw);
|
|
hr = pmiw->InvokeByName(
|
|
L"Value", CorFFIGetProperty, 0, NULL, &var);
|
|
pmiw->Release();
|
|
|
|
if (FAILED(hr))
|
|
fail("get_Value failed");
|
|
|
|
if (V_VT(&var) != VT_I4) {
|
|
fail("Expected VT_I4");
|
|
}
|
|
|
|
sum += V_I4(&var);
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
// errorinfo roundtrip
|
|
extern "C" HRESULT __stdcall ReallyBadError(IUnknown *punk)
|
|
{
|
|
HRESULT hr;
|
|
IErrorInfo* err;
|
|
ICreateErrorInfo *cerr;
|
|
BSTR bstr;
|
|
WCHAR buf[10000];
|
|
IManagedInstanceWrapper* pmiw;
|
|
|
|
punk->QueryInterface(IID_IManagedInstanceWrapper, (void**)&pmiw);
|
|
hr = pmiw->InvokeByName(
|
|
L"BadError", CorFFIInvokeMethod, 0, NULL, NULL);
|
|
pmiw->Release();
|
|
|
|
if (GetErrorInfo(0, &err) != S_OK)
|
|
fail("No error info!");
|
|
|
|
err->GetDescription(&bstr);
|
|
// printf("Description: %S\n", bstr);
|
|
err->Release();
|
|
|
|
_snwprintf(buf, 10000, L"qwerty %s", bstr);
|
|
SysFreeString(bstr);
|
|
|
|
if (CreateErrorInfo(&cerr) != S_OK)
|
|
fail("Failed to create error info!");
|
|
|
|
cerr->SetDescription(buf);
|
|
|
|
cerr->QueryInterface(IID_IErrorInfo, (void**)&err);
|
|
cerr->Release();
|
|
|
|
SetErrorInfo(0, err);
|
|
err->Release();
|
|
|
|
return E_FAIL;
|
|
}
|
|
|
|
// exception roundtrip
|
|
extern "C" void __stdcall Exception12345678(MyDelegate pfn, IUnknown* punk)
|
|
{
|
|
BOOL fException = FALSE;
|
|
PAL_TRY {
|
|
pfn(punk);
|
|
}
|
|
PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
|
fException = TRUE;
|
|
}
|
|
PAL_ENDTRY
|
|
|
|
if (!fException) {
|
|
fail("No exception thrown from managed code!");
|
|
}
|
|
|
|
RaiseException(0x12345678, EXCEPTION_NONCONTINUABLE_EXCEPTION, 0, NULL);
|
|
}
|
|
|
|
extern "C" MySimpleDelegate DelegateMarshal(MySimpleDelegate d)
|
|
{
|
|
return d;
|
|
}
|