//
enum EObjectType
{
Hello = 0,
GraphicAlgorithm
};
__declspec(dllexport) void * __stdcall Create(EObjectType AType)
{
if (AType == Hello) return new CHello();
if (AType == GraphicAlgorithm) return new CGraphicAlgorithm();
return NULL;
}
EXPORTS
Create
//
// {08356CFE-A3DD-43c2-980C-1393E37118B2}
static const GUID IID_IHello =
{ 0x8356cfe, 0xa3dd, 0x43c2, { 0x98, 0xc, 0x13, 0x93, 0xe3, 0x71, 0x18, 0xb2 } };
class IHello : public CBaseUnknown
{
public :
STDHRESULTMETHOD SetName(LPWSTR AName) = 0;
STDHRESULTMETHOD Say(HWND AParent) = 0;
};
class CHello :
public IHello
{
public :
STDHRESULTMETHOD QueryInterface( const CLSID &AId, void ** ARet)
{
__super::QueryInterface(AId, ARet);
if (AId == IID_IHello) *ARet = (IHello*) this ;
return (*ARet != NULL) ? S_OK : E_NOINTERFACE;
}
STDHRESULTMETHOD SetName(LPWSTR AName)
{
mName = AName;
return S_OK;
}
STDHRESULTMETHOD Say(HWND AParent)
{
wstring message = L "Hello, my friend " + mName;
MessageBox(AParent, message.c_str(), L "From C++" , MB_ICONINFORMATION);
return S_OK;
}
private :
wstring mName;
};
// enum C#
public enum EObjectType : int
{
Hello = 0,
GraphicAlgorithm
}
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid ( "08356CFE-A3DD-43c2-980C-1393E37118B2" )]
public interface IHello
{
void SetName([MarshalAs(UnmanagedType.LPWStr)] string AName);
void Say( IntPtr AParent);
}
public class Lib
{
//
[DllImport( "Lib.dll" )]
protected static extern IntPtr Create(EObjectType AType);
//
public static object CreateObject(EObjectType AType)
{
IntPtr ptr = Create(AType);
return Marshal.GetObjectForIUnknown(ptr);
}
}
object hiObject = Lib.CreateObject(EObjectType.Hello);
IHello hello = hiObject as IHello;
hello.SetName(txtName.Text);
hello.Say(Handle);
STDMETHODIMP CGraphicAlgorithm::QueryInterface( const CLSID &AId, void ** ARet)
{
__super::QueryInterface(AId, ARet);
if (AId == IID_IGraphicAlgorithm) *ARet = (CBaseUnknown*) this ;
return (*ARet != NULL) ? S_OK : E_NOINTERFACE;
}
STDMETHODIMP CGraphicAlgorithm::MakeGrayScale( void * APointer, int AWidth, int AHeight)
{
RGBQUAD *p = (RGBQUAD*)APointer;
for ( int y = 0; y < AHeight; y++)
{
for ( int x = 0; x < AWidth; x++)
{
// :)
short mid = (( short )p->rgbBlue + p->rgbGreen + p->rgbRed) / 3;
if (mid > 255) mid = 255;
BYTE v = (BYTE)mid;
memset(p, v, 3);
p++;
}
}
return S_OK;
}
STDMETHODIMP CGraphicAlgorithm::MakeAlpha( void * APointer, int AWidth, int AHeight)
{
RGBQUAD *p = (RGBQUAD*)APointer;
for ( int y = 0; y < AHeight; y++)
{
for ( int x = 0; x < AWidth; x++)
{
// , :)
memset(p, p->rgbReserved, 4);
p++;
}
}
return S_OK;
}
// {65ACBBC0-45D2-4622-A779-E67ED41D2F26}
static const GUID IID_IGraphicAlgorithm =
{ 0x65acbbc0, 0x45d2, 0x4622, { 0xa7, 0x79, 0xe6, 0x7e, 0xd4, 0x1d, 0x2f, 0x26 } };
class CGraphicAlgorithm : CBaseUnknown
{
public :
STDHRESULTMETHOD MakeGrayScale( void * APointer, int AWidth, int AHeight);
STDHRESULTMETHOD MakeAlpha( void * APointer, int AWidth, int AHeight);
STDHRESULTMETHOD QueryInterface( const CLSID &AId, void ** ARet);
};
IGraphicAlgorithm utils = Lib.CreateObject(EObjectType.GraphicAlgorithm) as IGraphicAlgorithm;
BitmapData data = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
if (optGray.Checked)
utils.MakeGrayScale(data.Scan0, data.Width, data.Height);
else
utils.MakeAlpha(data.Scan0, data.Width, data.Height);
bmp.UnlockBits(data);
picDest.Image = bmp;
picSrc.Refresh();
picDest.Refresh();
Source: https://habr.com/ru/post/101589/