Sending string from COM to C# under Vista problem
-
Hi, I'm experiencing and issue regarding System.AccessViolationException : Attempted to read or write protected memory that occurs since Vista. On XP's or previous, everything run fine. To be more specific. I have a C++ ATL/COM object (created in VS 6) that is wrapped in C# .NET 2.0 . Problem occurs when handling Strings. I've created COM using standard tools in VS 6. this is the method definition from Interface IDL file :
[id(9), helpstring("method GetString")] HRESULT GetString([out] LPSTR* word, [out, retval] int* count);
Inferface .h Header file :
STDMETHOD(GetString)(/*[out]*/ LPSTR* word, /*[out, retval]*/ int* count);
Code Inferface.c file :
STDMETHODIMP CLicenser::GetString(LPSTR* word, int *count)
{
// helper class is some class that provides information that we need...\*count = this->helperClass.GetCount(); // count works fine anytime. \*word = this->helperClass.GetWord(); // this causes Attemped to read or write protected memory... // \*word = "some text"; // !!! this works fine, if former line is commented out, this method throws // no Exception !!!. cout << "word:" << \*word << endl; // word is displayed correctly in console window (Console is created by //C# application) everytime return S\_OK;
}
Method definition in C# wrapper looks like:
int IClassNameObject.GetString(out string);
Anytime this method is called, it finishes properly (also including that Console output word:[whatever word contains]), besides in Vista, it throws that System.AccessViolationException with name of that (GetString) method after it finishes. Method is Supposed to return a count and fill a supplied string. If u need I can create sample project / dll , I don't have one now....
zilo
-
Hi, I'm experiencing and issue regarding System.AccessViolationException : Attempted to read or write protected memory that occurs since Vista. On XP's or previous, everything run fine. To be more specific. I have a C++ ATL/COM object (created in VS 6) that is wrapped in C# .NET 2.0 . Problem occurs when handling Strings. I've created COM using standard tools in VS 6. this is the method definition from Interface IDL file :
[id(9), helpstring("method GetString")] HRESULT GetString([out] LPSTR* word, [out, retval] int* count);
Inferface .h Header file :
STDMETHOD(GetString)(/*[out]*/ LPSTR* word, /*[out, retval]*/ int* count);
Code Inferface.c file :
STDMETHODIMP CLicenser::GetString(LPSTR* word, int *count)
{
// helper class is some class that provides information that we need...\*count = this->helperClass.GetCount(); // count works fine anytime. \*word = this->helperClass.GetWord(); // this causes Attemped to read or write protected memory... // \*word = "some text"; // !!! this works fine, if former line is commented out, this method throws // no Exception !!!. cout << "word:" << \*word << endl; // word is displayed correctly in console window (Console is created by //C# application) everytime return S\_OK;
}
Method definition in C# wrapper looks like:
int IClassNameObject.GetString(out string);
Anytime this method is called, it finishes properly (also including that Console output word:[whatever word contains]), besides in Vista, it throws that System.AccessViolationException with name of that (GetString) method after it finishes. Method is Supposed to return a count and fill a supplied string. If u need I can create sample project / dll , I don't have one now....
zilo
From your description, it looks like the problem is with the helperClass member. How does that work? Nathan
-
Hi, I'm experiencing and issue regarding System.AccessViolationException : Attempted to read or write protected memory that occurs since Vista. On XP's or previous, everything run fine. To be more specific. I have a C++ ATL/COM object (created in VS 6) that is wrapped in C# .NET 2.0 . Problem occurs when handling Strings. I've created COM using standard tools in VS 6. this is the method definition from Interface IDL file :
[id(9), helpstring("method GetString")] HRESULT GetString([out] LPSTR* word, [out, retval] int* count);
Inferface .h Header file :
STDMETHOD(GetString)(/*[out]*/ LPSTR* word, /*[out, retval]*/ int* count);
Code Inferface.c file :
STDMETHODIMP CLicenser::GetString(LPSTR* word, int *count)
{
// helper class is some class that provides information that we need...\*count = this->helperClass.GetCount(); // count works fine anytime. \*word = this->helperClass.GetWord(); // this causes Attemped to read or write protected memory... // \*word = "some text"; // !!! this works fine, if former line is commented out, this method throws // no Exception !!!. cout << "word:" << \*word << endl; // word is displayed correctly in console window (Console is created by //C# application) everytime return S\_OK;
}
Method definition in C# wrapper looks like:
int IClassNameObject.GetString(out string);
Anytime this method is called, it finishes properly (also including that Console output word:[whatever word contains]), besides in Vista, it throws that System.AccessViolationException with name of that (GetString) method after it finishes. Method is Supposed to return a count and fill a supplied string. If u need I can create sample project / dll , I don't have one now....
zilo
If not used in any other projects I would strongly recommend that you stick to Automation-compatible types, so here you would use a BSTR rather than LPSTR. .NET understands Automation types better than raw types. If you can't do this, you need to ensure that the marshalling and memory model are followed correctly. You need to tell MIDL that the parameter is actually a null-terminated string (use the
string
attribute in addition toout
) so that the data is marshalled correctly. Otherwise it assumes that the LPSTR points to a singlechar
. For returning a string, you must return a new buffer allocated with the system allocator,CoTaskMemAlloc
. I suspect what's happening is that .NET is trying to free the returned pointer by callingCoTaskMemFree
and in Windows XP, you were getting away with it.
DoEvents
: Generating unexpected recursion since 1991 -
If not used in any other projects I would strongly recommend that you stick to Automation-compatible types, so here you would use a BSTR rather than LPSTR. .NET understands Automation types better than raw types. If you can't do this, you need to ensure that the marshalling and memory model are followed correctly. You need to tell MIDL that the parameter is actually a null-terminated string (use the
string
attribute in addition toout
) so that the data is marshalled correctly. Otherwise it assumes that the LPSTR points to a singlechar
. For returning a string, you must return a new buffer allocated with the system allocator,CoTaskMemAlloc
. I suspect what's happening is that .NET is trying to free the returned pointer by callingCoTaskMemFree
and in Windows XP, you were getting away with it.
DoEvents
: Generating unexpected recursion since 1991Hi, I wasn't able to replace LPSTR with BSTR. My knowledge about C++ is limited and I did not find corresponding conversion. Anyway, I added
string
attribute and started usingCoTaskMemAlloc
on C++ side and so far it's working under Vista too, so thank you very much! :rose:zilo