Hello people, I have probably a similar problem. Has anyone know how to resolve the problem?

Hello people, I have probably a similar problem. Has anyone know how to resolve the problem?

My Delphi is Enterprise - Berlin

The event (into the Delphi COM server) has string parameters and if the event is triggered with blank string values (empty strings '')(all or some of them), it will not be fired in C# program because an exception is raised. The raised exception message is: Invalid pointer.
but...
There no such problem if the clients application is a Delphi application. The Delphi client application works perfectly.

If the string parameter has only one character also, the event will be fired into the C# application without an exception.

Any ideas?
:(
https://stackoverflow.com/questions/22675815/com-event-not-triggered-in-c-sharp-for-delphi-com-objects-with-empty-values-in-s

Comments

  1. Hm... maybe the answer is in the usage of SysAllocString - a method which I not use in this case. I'll post the results tomorrow - for now bye from me.

    ReplyDelete
  2. Likely a string lifetime management thing on either side of the interface. COM uses PChar so you need to ensure the string backing storage lives long enough for the event but short enough not to cause a memory leak.

    Make a reproducible case showing the full code on both sides of the interface.

    ReplyDelete
  3. Jeroen Wiert Pluimers Er, COM strings are BSTR, not PChar, allocated on the shared COM heap by calling SysAllocString.

    ReplyDelete
  4. Dobrin Petkov​ This is surely easy to answer with a minimal reproduction.

    ReplyDelete
  5. David Heffernan Yup, you are right. I mixed up COM with P/Invoke. Reproducible case still applies.

    ReplyDelete
  6. ridl source:
    Hello - sorry for the delayed answer. Here is an example of my Delphi COM Server code:

    ridl source:
    -----------------------------------------
    dispinterface ICMYCOMServerEvents
    {
    properties:
    methods:
    ...
    [id(0x000000D4)]
    HRESULT OnSendCommand([in] BSTR Command, [in] BSTR hex_Header, [in] BSTR hex_Data, [in] BSTR hex_Footer, [in] BSTR human_Data);
    ...
    };
    ---------------------------------------

    TLB source:
    -----------------------------------------
    ICMYCOMServerEvents = dispinterface
    ...
    function OnSendCommand(const Command: WideString; const hex_Header: WideString;
    const hex_Data: WideString; const hex_Footer: WideString;
    const human_Data: WideString): HResult; dispid 212;
    -----------------------------------------

    Implementation:
    -----------------------------------------
    procedure TCMYCOMServerEvent.send_SendCommand(const Command, hex_Header, hex_Data, hex_Footer, human_Data: WideString);
    var
    Enum : IEnumConnections;
    ConnectData : TConnectData;
    Fetched : Cardinal;
    begin
    Enum := GetEnumerator;
    if Enum <> nil then
    while Enum.Next(1, ConnectData, @Fetched) = S_OK do
    if ConnectData.pUnk <> nil then
    (ConnectData.pUnk as ICMYCOMServerEvents).OnSendCommand(
    Command,
    hex_Header,
    hex_Data,
    hex_Footer,
    human_Data);
    end;
    -----------------------------------------

    For example If hex_Data or human_Data are empty strings - this code raise an exception if client side is C# application.
    No problems with Delphi clients

    ReplyDelete
  7. at the C# side - this is enough:
    ...
    _serv = new CMYCOMServer();
    if (_serv != null)
    {
    ...
    this.serv.OnSendCommand += Serv_OnSendCommand;
    }
    ...
    private void Serv_OnSendCommand(string Command, string hex_Header, string hex_Data, string hex_Footer, string human_Data)
    {
    //
    }
    ...

    Note: C# code is not mine.

    ReplyDelete
  8. Delphi events fired as a result of execution of some commands to the device via RS-232. The client side can log data into the file or show the data (or something else).

    ReplyDelete
  9. This isn't complete. We can't execute this because of that. Read this http://sscce.org

    ReplyDelete
  10. David Heffernan You are right - sorry for that.

    ReplyDelete
  11. The usage of "SysAllocString('');" not helped much - Delphi raise the same exception but I found how to resolve (or avoid) the problem.
    -
    My solution:
    1. Change the ridl description of parameters to [in, out].
    - From:
    -- "HRESULT OnSendCommand([in] BSTR Command, [in] BSTR hex_Header, [in] BSTR hex_Data, [in] BSTR hex_Footer, [in] BSTR human_Data);"
    - to the:
    -- "HRESULT OnSendCommand([in, out] BSTR* Command, [in, out] BSTR* hex_Header, [in, out] BSTR* hex_Data, [in, out] BSTR* hex_Footer, [in, out] BSTR* human_Data);"

    2. Update the reference into the C# project;
    3. Change the implementation into the C# code to:
    private void Serv_OnSendCommand(ref string Command, ref string hex_Header, ref string hex_Data, ref string hex_Footer, ref string human_Data)
    {
    string tmp_Command = Command != null ? Command : "";
    string tmp_hex_Header = hex_Header != null ? hex_Header : "";
    string tmp_hex_Data = hex_Data != null ? hex_Data : "";
    string tmp_hex_Footer = hex_Footer != null ? hex_Footer : "";
    string tmp_human_Data = human_Data != null ? human_Data : "";
    ...
    and use tmp_xx values!

    That is all for now.

    ReplyDelete
  12. Dobrin Petkov which very much points the root cause being a string lifetime management issue.

    Note that the change of parameter totally alters the meaning of your interface. And it steps away from solving G your root cause, which now will bite you in a different place at a time you're even less prepared for it.

    ReplyDelete
  13. You've not fixed anything there at all. You've merely swept the problem under the carpet.

    ReplyDelete
  14. All you are right - this is not a proper fix. Avoiding of the problem for now is more close to the situation as description of my temporary solution.
    But I can't share the entire project. I will try to make some new example projects (according to the recommendations of David Heffernan) after few days and will post them here.

    ReplyDelete
  15. Dobrin Petkov now you are moving in the right direction. Well done. I am
    looking forward to your new posts.

    ReplyDelete

Post a Comment