|
|
Even better - many thanks!
Which begs the question: why didn't it show up in my Google and MSDN search?
/ravi
|
|
|
|
|
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
<br />
[System.Runtime.InteropServices.DllImport("mydll.dll")]<br />
static extern unsafe bool theFunc([MarshalAs(UnmanagedType.Interface)] theItem item, StringBuilder buffer);<br />
<br />
StringBuilder buffer = new StringBuilder(1024);<br />
try<br />
{<br />
bRet = teFunc(_o, buffer);<br />
}...<br />
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
|
|
|
|
|
realmontanakid wrote: Any ideas?
How is native code going to be able to use a StringBuilder object?
led mike
|
|
|
|
|
Mike, this is standard procedure when passing in strings into functions that are expected to modify the string.
|
|
|
|
|
Yes forgot that, had to go look it up again!
However if the native code will write to it the signature should include a bufferSize argument which is the preallocated StringBuffer.Capacity, yes?
led mike
|
|
|
|
|
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.
|
|
|
|
|
I can do it with a StringBuilder or like this,
<br />
byte[] buffer = new byte[512];<br />
<br />
unsafe<br />
{<br />
fixed (byte* pBuffer = buffer)<br />
{<br />
ret = theFunc(_o, pBuffer);<br />
}<br />
}<br />
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
|
|
|
|
|
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.
|
|
|
|
|
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 ?
|
|
|
|
|
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...
|
|
|
|
|
Hello everyone,
Is it possible to create enumerations dynamically which we can manipulate or even create/destroy at run-time?
Best regards.
.:: Something is Wrong ::.
|
|
|
|
|
Yes it is possible. Look up Lightweight Code Generation.
That said, I'd question whether you truly need this; there's probably an easier way to accomplish your goal. What are you trying to do? I may be able to suggest a better alternative.
|
|
|
|
|
Well, for example, I would like to create a generic vehicle class, in which I should use a vehicle type enumeration. But when someone needs to extend this types he/she should add some ne vehicle types to the enumeration.
.:: Something is Wrong ::.
|
|
|
|
|
Use a list or a database rather than a dynamic enum.
|
|
|
|
|
Absolutely. However an enumeration is the wrong data type to use. A collection of some sort would do just as well. With the lists (i.e. ArrayList), you can even sort the list and do a binary search on the list to find out if the element exists. But I am thinking that you want to do a direct comparison, which means that you can do a list.Equals(value) which returns a true or a false.
Phil
|
|
|
|
|
let's say i want to go to address 377DC in program.exe and change it's value to 60? (just a fictional example), how can I do it?
|
|
|
|
|
You can acquire pointers to memory locations use standard pointer syntax ala C++. It just has to be done in an unsafe context using the unsafe keyword.
|
|
|
|
|
um..have you got any examples? cause i haven't been able to find any references to that subject
|
|
|
|
|
sharpiesharpie wrote: i haven't been able to find any references to that subject
What did you search on? MSDN: unsafe[^]
|
|
|
|
|
Are you trying to change something in some other running program?
Or you trying to this in an application written by you?
|
|
|
|
|
In another program (games). I just want to learn the whole thing (used to build trainers etc.).
|
|
|
|
|
I knew that you can use DLL Injection in VC++ however I am not sure how to achive it in VC#.
btw I dont think you can do it in any NT based OS. That is the security model to stop one process to modify(tamper) some other process unless explicitly allowed.
Cheers,
Suresh
|
|
|
|
|
lol...ever heard of trainers? and you don't even have to go that far, just google "TSearch"...a memory searcher used to search a program's memory and change values in it.
|
|
|
|