|
I suspect that rather than 'new BSTR', you should use CoTaskMemAlloc[^] to allocate memory in a COM server:
BSTR *pBSTR = (BSTR*)CoTaskMemAlloc(sizeof(BSTR));
However - one other thing strikes me - why pass the BSTR back by reference? Why not use this?
VariantClear( p );
VariantInit( p );
p->vt = VT_BSTR;
p->pbstrVal = SysAllocString( L"abc" );
One less allocation, one less place to leak memory!
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Hi
The same happens with CoTaskMemAlloc, and using VT_BSTR instead of VT_BSTR | VT_BYREF.
Thanks anyway.
|
|
|
|
|
How CallService is defined in IDL file? If it's "CallService([in] VARIANT *p1)", then you cannot change the parameter. If it's "CallService([in,out] VARIANT *p1), then you cannot receive the parameter in Integer.
IAC, VB passes myInt variable as VT_BYREF | VT_I2 to be possible to change the myInt value. It's made only during call some method. Inside VB don't store variant by this manner.
STDMETHODIMP CDCSClient::CallService( VARIANT *p )
{
VariantClear( p );
p->vt = VT_BSTR;
p->bstrVal = SysAllocString( L"abc" );
return S_OK;
}
If you desire to pass BSTR by reference, you should keep out this address and make sure to free this BSTR after using.
BSTR g_pBSTR = NULL; // global scope, so somewhere should be "if (!g_pBSTR) SysFreeString(g_pBSTR);"
STDMETHODIMP CDCSClient::CallService( VARIANT *p )
{
VariantClear( p );
p->vt = VT_BSTR | VT_BYREF;
if (!g_pBSTR) g_pBSTR = SysAllocString( L"abc" );
p->pbstrVal = &g_pBSTR;
return S_OK;
}
With best wishes,
Vita
|
|
|
|
|
The parameter is defined as [in,out,optional].
And yes, now I understand, as I suspected, I can't reallocate the VT_BYREF | VT_I2 inside my ATL code.
The only thing still not 100% clear which confused me is that I can define a VB procedure receiving a byref variant, do the same thing receiving my int, and changing it to String and no leak happens. That was my first test.
But the difference is: there's no COM in this scenario, and the pure VB allocation\dellocation mechanisms are not the same.
Thanks a lot !
|
|
|
|
|
STDMETHODIMP CDCSClient::CallService( VARIANT *p)
{
if (V_VT(p) == (VT_VARIANT | VT_BYREF))
{
VARIANT *p2 = V_VARIANTREF(p);
p2->vt = VT_BSTR;
p2->bstrVal = SysAllocString( L"abc" );
return S_OK;
}
}
Dim v As Variant
v = 1
Debug.Print TypeName(v) & " " & v
Call obj.CallService(v)
Debug.Print TypeName(v) & " " & v
With best wishes,
Vita
|
|
|
|
|
About memory leaks. VB allocation\dellocation mechanisms are the same with COM.
p->vt = VT_BSTR | VT_BYREF;
BSTR *pBSTR = new BSTR;
*pBSTR = SysAllocString( L"abc" );
p->pbstrVal = pBSTR;
There are 2 memory allocations in statements "= new BSTR" and "= SysAllocString".
The VARIANT with VT_BYREF|VT_BSTR isn't an owner of its values, so freeing of the VARIANT doesn't free neither pbstrVal nor *pbstrVal. And finally you have memory leaks.
The VARIANT with VT_BSTR (without VT_BYREF) is an owner of its values, so freeing of the VARIANT frees bstrVal.
p->vt = VT_BSTR;
p->bstrVal = SysAllocString( L"abc" );
And there are no memory leaks.
With best wishes,
Vita
|
|
|
|
|
Hi,
I am trying to call the Win 32 API messagebox function from c#.
However, i finding my code not working:
could you please help me correct it:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ConsoleApplication5
{
class Program
{
public const String UserReference = "user32.dll";
[DllImport(UserReference, SetLastError = true)]
private static extern Int32 MessageBox(IntPtr hWnd, String pText,
String pCaption, Int32 uType);
static void Main(string[] args)
{
IntPtr ProblemCauser = (IntPtr)(-100);
MessageBox(ProblemCauser, "hello", "check", 0);
Int32 ErrorCode = Marshal.GetLastWin32Error();
Console.WriteLine("Error Code: " + ErrorCode.ToString());
Console.ReadLine();
}
}
}
|
|
|
|
|
Your arguments are invalid!
nicetohaveyou wrote: IntPtr ProblemCauser = (IntPtr)(-100) .
-100 is a number not pointer to valid window.
Call it like that
MessageBox(this.Handle,"hello", "check", 0)
into Form body or
MessageBox(IntPtr.Zero,"hello", "check", 0)
|
|
|
|
|
On one side I have a C# application (WPF) from which I want to call an Office Add-In class. On my Office Add-In project I've exposed a class and an interface to COM. I'm able to call functions from my exposed Add-In object, but I'm not able to register an event, which should by fired by the exposed Add-In project.
My C# code:
officeAddIn = excel.COMAddIns.Item(ref addinName);
object obj = officeAddIn.Object;
IAddInUtilities m_excelFIMAddInUtils = (IAddInUtilities)obj;
AddInEnablingEventHandler addInEnablingEventHandler = new AddInEnablingEventHandler(m_excelFIMAddInUtils_AddInEnablingEvent);
m_excelFIMAddInUtils.EnableAddIn(true);
m_excelFIMAddInUtils.AddInEnablingEvent += addInEnablingEventHandler
My AddIn Project:
[ComVisible(false)]
[Serializable()]
public delegate void AddInEnablingEventHandler();
public partial class ExcelFIMAddIn
{
private AddInFIMUtilities m_utilities;
private Office.IRibbonExtensibility m_ribbon;
protected override object RequestComAddInAutomationService()
{
if (m_utilities == null)
{
m_utilities = new AddInFIMUtilities();
}
return m_utilities;
}
protected override Office.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
RibbonExcelFIM ribbon = new RibbonExcelFIM();
ribbon.FIMSaveEvent += new FIMSaveEventHandler(ribbon_FIMSaveEvent);
return ribbon;
}
}
[Guid("6CA66587-1A1E-4cd6-B55A-20F07F18C343")]
[ComVisibleAttribute(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddInUtilities
{
void EnableAddIn(bool isAddInEnabled);
event AddInEnablingEventHandler AddInEnablingEvent;
}
[ComVisibleAttribute(true)]
[Guid("F2FA4759-AEA0-4f4e-838B-3BBBC77837AB")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("AddInFIMUtilites")]
[Serializable()]
public class AddInFIMUtilities : StandardOleMarshalObject, IAddInUtilities
{
public event AddInEnablingEventHandler AddInEnablingEvent;
public void EnableAddIn(bool isAddInEnabled)
{
m_isAddInEnabled = isAddInEnabled;
if (isAddInEnabled)
{
if (AddInEnablingEvent != null)
{
AddInEnablingEvent();
}
else
{
}
}
}
}
What I'm doing wrong? Is there a solution which someone can provide me?
Thanks in advance
Marcel
|
|
|
|
|
I found out a solution that works. If someone has a better working solution, please post it
The code snippet of my new code in C#:
m_excelAddInUtils = (IAddInUtilities)obj;
IpcChannel serverChannel = new IpcChannel("localhost:0");
ChannelServices.RegisterChannel(serverChannel);
AddInFIMUtilities addInUtilClass = new AddInFIMUtilities();
m_excelAddInUtils.AddToSaveObserverList(addInUtilClass);
addInUtilClass.AddInSaveEvent += new AddInSaveEventHandler(addInUtilClass_OnFIMSaved);
The new delegate in Add-In class:
public delegate void AddInSaveEventHandler();
On the Add-In class I created a new IDispatch Interface:
[Guid("69075652-6A6D-442c-B534-5816D5046F04")]
[ComVisibleAttribute(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IAddInEvents
{
void AddInSaveEventHandler();
}
And extended the Main method interface:
[Guid("6CA66587-1A1E-4cd6-B55A-20F07F18C343")]
[ComVisibleAttribute(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAddInUtilities
{
[DispId(1)]
void AddToSaveObserverList(IAddInUtilities addInUtils);
[DispId(2)]
void FireSaveEvent();
}
The new methods in the Utility class:
public void AddToSaveObserverList(IAddInUtilities addInUtils)
{
Globals.ExcelFIMAddIn.SaveObserverList.Add(addInUtils);
}
public void FireSaveEvent()
{
AddInSaveEvent();
}
On the Add-In class itself, these extensions are required:
<pre>private List<IAddInUtilities> m_saveObserverList = new List<IAddInUtilities>();
public List<IAddInUtilities> SaveObserverList
{
get { return m_saveObserverList; }
}
And eventually firing the event:
foreach (IAddInUtilities addInFIMUtil in this.SaveObserverList)
{
try
{
((AddInFIMUtilities)addInUtil).FireSaveEvent();
}
catch
{
}
}
modified on Monday, August 10, 2009 6:52 AM
|
|
|
|
|
Hi,
I am new to COM Component development. I dont have that much idea. So plz give me sample code or sample program. Thanks in Advance..
regards,
kannak....
kannak
|
|
|
|
|
|
Hi David...
Thanks for responding..i will go through ....
Regards,
kannak......
kannak
|
|
|
|
|
When I try to play an .avi file in a Windows Media Player component, it is like 1 second black between each new play. It says 'Media has been found' (a translation of myswlf of the Dutch version). Is this solvable? The avi file is a copy of the Vista copy file dialog which musn't be black between every loop.
Thanks.
|
|
|
|
|
Sorry for asking this question too fast - I found out that this component can play without any black pause in between!
Thanks.
|
|
|
|
|
How to set output parameter value to javascript use invoke function's pDispParams.
in javascript
<script type="text/javascript"><br />
var fVal;
external.GetFloat(fVal);<br />
</script>
How do it in Invoke function???
STDMETHODIMP CImpIDispatch::Invoke(<br />
DISPID dispIdMember,<br />
REFIID ,<br />
LCID ,<br />
WORD wFlags,<br />
DISPPARAMS* pDispParams,<br />
VARIANT* pVarResult,<br />
EXCEPINFO* ,<br />
UINT* puArgErr)<br />
{<br />
return S_OK;<br />
}
Hongjun Ge
|
|
|
|
|
You have no chance to transmit any value to javascript by parameter in parameter's list of GetFloat function. Only by [out,retval] parameter of one. I.e. by syntax "fVal = external.GetFloat();". For this action, you should assign right value to pVarResult parameter of CImpIDispatch::Invoke.
With best wishes,
Vita
|
|
|
|
|
Thanks for your reply.
In msdn document descriptions like below.Why they can implement the oCustCalenderObj parameter as out.
http://msdn.microsoft.com/en-us/library/aa770041(VS.85).aspx[^]
<SCRIPT language="JScript"><br />
function MyFunc(iSomeData)<br />
{<br />
var oCustCalendarObj;<br />
external.GetCustomCalender(oCustCalenderObj);<br />
oCustCalerdarObj.doStuffWithIt();<br />
.<br />
.<br />
.<br />
}<br />
</SCRIPT>
Hongjun Ge
|
|
|
|
|
I don't know, but all I said is correct. I didn't meet with GetCustomCalender declaration, but "Get" prefix requires [out,retval] parameter.
AFAIK JScript passes all arguments by value, so server doesn't have a way to modify them. And there is only one case - VARIANT* pVarResult parameter of Invoke.
You can assign some value to this parameter and view the result.
With best wishes,
Vita
|
|
|
|
|
Thanks for your reply. My be there have some way to implement it that we didn't find, But thanks again.
Hongjun Ge
|
|
|
|
|
I'm automating MS Word and so far I've found out that the easiest way to do it is to put as much of the code as possible in VBA macros (in a *.dot file loaded through COM automation), and call those macros.
m_Application.CreateDispatch(_T("Word.Application"));
...............
m_AddIns.AttachDispatch(m_Application.get_AddIns());
m_AddIn.AttachDispatch(m_AddIns.Add(_T("MyMacros.dot"), &vtOptional));
...............
m_Application.Run("MyMacro1");
The problem is I can't pass arguments to MyMacro1, and I need to in some cases. CApplication::Run accepts only 1 parameter and that's the macro name. But how can I pass additional arguments to the macro?
There is sufficient light for those who desire to see, and there is sufficient darkness for those of a contrary disposition.
Blaise Pascal
|
|
|
|
|
Hello,
I am trying to call an activeX method from JScript in IE6. The method we are trying to call takes two arguments: one long which is the dimension of the array (of bytes) passed as the second parameter. In some cases the size can be zero and the array undefined and we are in that case.
How can I call this method from my JScript code? I tried obj."method(0, null);" but I get an incompatible type error. I also tried using Scripting.Dictionary object but to no avail. Has anyone a tip for this ?
Thanks,
|
|
|
|
|
I'm building .NET application that uses DirectX API for web camera device rendering.
I'm using DirectShowNet Library as wrapper for more info see here DirectShow.NET[^]
When I create instance of for ICaptureGraphBuilder2 interface and call RenderStream like bellow
<br />
Guid cat = PinCategory.Capture;<br />
Guid med = MediaType.Video;<br />
<br />
hr = capGraph.RenderStream(ref cat, ref med, capFilter, null,null)<br />
where capFilter is my source filter,everything is OK.
But after releasing the resources and recreating the graph and the ICaptureGraphBuilder2 instance when I call the method RenderStream it failes with return code -2147024809 or HRESULT E_INVALIDARG.I've tried to call it like
<br />
hr =capGraph.RenderStream(ref cat, ref med, capFilter, null,target) <br />
,where target is my target filter,but this failes again with the same return code.When I change the category to PinCategory.Preview I'm also getting the same result.
I can't avoid using ICaptureGraphBuilder2,because I need to control the resolution of the device.
Do you know how to fix it?
Thank you very much!
|
|
|
|
|
I have solved the problem with using DirectShowLib ,newer version of the API.
Now everything works fine!

|
|
|
|
|
Hi guys,
working with some closed-code client/server application - the client reaches the server using a COM object thats defined by a InprocServer32 DLL - I would like to split client and server to different machines.
DCOM at first sight cannot do it - as the COM is a InprocServer32 DLL (for remoting a LocalServer32 COM - EXE seems to be necessary - Racmgr32 only lists these COM class entries).
My first thought was to code a InprocServer32 COM EXE that provides the same classes like the InprocServer32 DLL does. After I would generate the TLB of the DLL an generate a InprocServer32 DLL that has the same classes and interfaces, but just calls the LocalServer32 EXE - which after could be remotely used by help of DCOM. I guess this has do be done because if I just deleted the InprocServer32 class entry, the current creating method in my client-EXE would not be able to deal with the LocalServer32 COM class anymore.
My question now is - would You guys do it the same way? Does anyone know a way how to make a InprocServer32 DLL being usable remotely - for example by hooking up CreateDispatch? If I would do it the way I described - does anyone see problems or shortcomings? I am thankful for every articles and informations You drop!
Thank You very much for Your ideas, thoughts and replies!
Tiger
|
|
|
|