pinvoke COM function and damaged memory [modified]
-
Hello, i pinvoke a function from an com api. The function needs two parameters, an com interface and one out parameter. The prototype from the function is BOOL WINAPI theFunc(theObject* pObject, LPTSTR szName); My Call
[System.Runtime.InteropServices.DllImport("mydll.dll")] static extern unsafe bool theFunc([MarshalAs(UnmanagedType.Interface)] theItem item, StringBuilder buffer); StringBuilder buffer = new StringBuilder(1024); try { bRet = teFunc(_o, buffer); }...
In a normal Windows Application there is no error. The error occured only when i use the code in a c# Windows service. The exception is that the memory might be damaged... AccessViolationException Any ideas? -- modified at 14:54 Monday 16th April, 2007 -
Hello, i pinvoke a function from an com api. The function needs two parameters, an com interface and one out parameter. The prototype from the function is BOOL WINAPI theFunc(theObject* pObject, LPTSTR szName); My Call
[System.Runtime.InteropServices.DllImport("mydll.dll")] static extern unsafe bool theFunc([MarshalAs(UnmanagedType.Interface)] theItem item, StringBuilder buffer); StringBuilder buffer = new StringBuilder(1024); try { bRet = teFunc(_o, buffer); }...
In a normal Windows Application there is no error. The error occured only when i use the code in a c# Windows service. The exception is that the memory might be damaged... AccessViolationException Any ideas? -- modified at 14:54 Monday 16th April, 2007 -
Hello, i pinvoke a function from an com api. The function needs two parameters, an com interface and one out parameter. The prototype from the function is BOOL WINAPI theFunc(theObject* pObject, LPTSTR szName); My Call
[System.Runtime.InteropServices.DllImport("mydll.dll")] static extern unsafe bool theFunc([MarshalAs(UnmanagedType.Interface)] theItem item, StringBuilder buffer); StringBuilder buffer = new StringBuilder(1024); try { bRet = teFunc(_o, buffer); }...
In a normal Windows Application there is no error. The error occured only when i use the code in a c# Windows service. The exception is that the memory might be damaged... AccessViolationException Any ideas? -- modified at 14:54 Monday 16th April, 2007Is theItem being marshalled right? From the stuff you posted, I don't see anything that appears to be wrong. *edit* are you sure you need StringBuilder? I don't think it will hurt, however, you should only use StringBuilder if the native method will be modifying/creating the string.
Tech, life, family, faith: Give me a visit. I'm currently blogging about: How men in the Catholic Church replaced Passover with Easter The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
-
realmontanakid wrote:
Any ideas?
How is native code going to be able to use a StringBuilder object? :confused:
led mike
Mike, this is standard procedure when passing in strings into functions that are expected to modify the string.
Tech, life, family, faith: Give me a visit. I'm currently blogging about: How men in the Catholic Church replaced Passover with Easter The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
-
Is theItem being marshalled right? From the stuff you posted, I don't see anything that appears to be wrong. *edit* are you sure you need StringBuilder? I don't think it will hurt, however, you should only use StringBuilder if the native method will be modifying/creating the string.
Tech, life, family, faith: Give me a visit. I'm currently blogging about: How men in the Catholic Church replaced Passover with Easter The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
I can do it with a StringBuilder or like this,
byte[] buffer = new byte[512]; unsafe { fixed (byte* pBuffer = buffer) { ret = theFunc(_o, pBuffer); } }
The second Parameter is an out param, it gives me a path to a file. If i do it with a StringBuilder or with a pointer to a buffer, it is the same result. In a Windows Forms Application, the buffer is NOT empty, in a Windows Service the buffer IS empty.. I try it on different machines and with different user accounts (Local System, User etc.). In a service it won't work.The com interface is marshalled correct. Attempted to read or write protected memory. This is often an indication that other memory is corrupt." -- modified at 17:29 Monday 16th April, 2007 -
Mike, this is standard procedure when passing in strings into functions that are expected to modify the string.
Tech, life, family, faith: Give me a visit. I'm currently blogging about: How men in the Catholic Church replaced Passover with Easter The apostle Paul, modernly speaking: Epistles of Paul Judah Himango
-
I can do it with a StringBuilder or like this,
byte[] buffer = new byte[512]; unsafe { fixed (byte* pBuffer = buffer) { ret = theFunc(_o, pBuffer); } }
The second Parameter is an out param, it gives me a path to a file. If i do it with a StringBuilder or with a pointer to a buffer, it is the same result. In a Windows Forms Application, the buffer is NOT empty, in a Windows Service the buffer IS empty.. I try it on different machines and with different user accounts (Local System, User etc.). In a service it won't work.The com interface is marshalled correct. Attempted to read or write protected memory. This is often an indication that other memory is corrupt." -- modified at 17:29 Monday 16th April, 2007Hi, StringBuilder is the right way to go when the function wants to return a string value; it would be better to have a buffer size too in the argument list (it would then be set to StringBuilder.Capacity), but if the function does not take such an input, you should provide a sufficiently large StringBuilder. For a single file spec, I believe 512 is the Windows maximum. When I must call a native function that does not take a buffer size, I provide a StringBuilder[1024]. I am afraid it is the other, the first, argument, that is causing your problems. :)
Luc Pattyn [My Articles]
-
Hi, StringBuilder is the right way to go when the function wants to return a string value; it would be better to have a buffer size too in the argument list (it would then be set to StringBuilder.Capacity), but if the function does not take such an input, you should provide a sufficiently large StringBuilder. For a single file spec, I believe 512 is the Windows maximum. When I must call a native function that does not take a buffer size, I provide a StringBuilder[1024]. I am afraid it is the other, the first, argument, that is causing your problems. :)
Luc Pattyn [My Articles]
Hi, no the first argument is not the problem. I'm testing with a StringBuilder with a capacity from up to 10240 to ensure there is enough space.. but it don't work. That makes me crazy. So, i got a little Form Application with one button, on button click event i call the function and it works. When i do it in a ConsoleApp or a service it will not work. I don't think that my code is ugly.. i think here is something wrong with the hole frame. Is ther probably not enough or to much time between call and passing the function? Or could it be a Thread Problem?
-
Hi, no the first argument is not the problem. I'm testing with a StringBuilder with a capacity from up to 10240 to ensure there is enough space.. but it don't work. That makes me crazy. So, i got a little Form Application with one button, on button click event i call the function and it works. When i do it in a ConsoleApp or a service it will not work. I don't think that my code is ugly.. i think here is something wrong with the hole frame. Is ther probably not enough or to much time between call and passing the function? Or could it be a Thread Problem?
OK, lets suppose the marshalling is all right. two ideas: 1. What is special about the service ? what is the string you expect to get ? does it exist when there is no user logged in ? 2. a simple test may not call the gc and work fine, what if the gc starts acting up. Are you passing some pointer somewhere that needs to be pinned so the gc does not MOVE the object ? :)
Luc Pattyn [My Articles]
-
Hi, no the first argument is not the problem. I'm testing with a StringBuilder with a capacity from up to 10240 to ensure there is enough space.. but it don't work. That makes me crazy. So, i got a little Form Application with one button, on button click event i call the function and it works. When i do it in a ConsoleApp or a service it will not work. I don't think that my code is ugly.. i think here is something wrong with the hole frame. Is ther probably not enough or to much time between call and passing the function? Or could it be a Thread Problem?
Another idea: check the STAThread/MTAThread situation for your different experiments. It is an attribute that gets set automatically to your static Main() method. BTW: Having the console app fail is good, it may allow you an easy debug with Visual Studio... :)
Luc Pattyn [My Articles]