|
This is the code that I wrote:
using System;
unsafe class Class1
{
public byte* pBytes;
unsafe static void Main()
{
byte[] mArr= new byte[]{6,9,11,25};
fixed (pBytes = mArr)
{
for(int i= 0; i<4;i++)
Console.WriteLine(pBytes[i]);
}
}
}
|
|
|
|
|
Not that your example is any indication of what you are actually doing, but keep in mind that C# does turn off bounds checking for cases like
for(int i=0; i
|
|
|
|
|
Why do you need to use an unsafe context for this? mArr is your "pointer" to the array of bytes, except that in the managed code world it's called references, which can be moved around by the garbage collector (GC) in the heap whenever it needs to optimize memory (which is why you must use the fixed keyword, or the GCHandle class to lock the object on the heap for that context). Arrays are also reference types, so you don't need to use ref or out with them except in some uncommon cases when you need to declare an undimensioned array and have a method (not "function") return it.
The code can simply be:
byte[] mArr = new byte[] {6, 9, 11, 25};
for (int i=0; i<mArr.Length; i++)
Console.WriteLine("0x{0:x2}", mArr[i]); Much easier, and correct (since unsafe contexts cause security problems in non-local deployments and are not completely managed by the CLR).
Even if this is a field in your class, it doesn't matter:
public class MyClass
{
public byte[] bytes;
public MyClass()
{
bytes = new byte[] {6, 9, 11, 25};
}
} Your declaration of the byte[] array doesn't dimension it; it only declares an array of a certain type. In unmanaged code, the same is true, since a char* points to the first element (the pointer to the array itself) of a char[] , for example.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yes, that's ok.
But I still having troubles to fill a member field, (array of bytes), with the data returned by a function called from a thread.
Example:
<br />
class myClass<br />
{<br />
public Array m_arr;
<br />
public void MyThreadMethod()<br />
{<br />
object ret; <br />
ret=AFunction(Aparam);
Array ar = (Array) ret;
m_arr=ar;
}
I can't fill my member variable with data of the thread.
Regards.
|
|
|
|
|
You typically don't declare an Array , but an array of something like byte[] , which I mentioned before. This does not have dimension.
Also, why not return the actual array from AFunction ? All this casting is completely unnecessary. So long as this is all .NET code, you can pass and return anything, but you must understand the difference between value and reference types (you're dealing with reference types here). If AFunction is a P/Invoke method, then things are a bit different. Is this the case?
If it's all coded for .NET (no P/Invoke or COM interop), you could simply use m_arr = AFunction(Aparam); it the method was declared appropriately. Return an object or taking an object as a param is really only a good idea when you don't know what to expect (or in some polymorphic designs when derivative classes will accept different types).
The only times when assign data from a thread is a problem is when 1) you don't lock your resource and multiple threads write to it/assign at the same time, or 2) when you try to update the UI (like setting the Text property of a control or adding a ListViewItem to a ListView ). For this latter case, make use of the Control.InvokeRequired property (to determine if the following method should be used) and the Control.Invoke method.
In any case, this should definitely work if its purely managed code. I do it all the time. Please provide more information (and accurate to your actual problem, instead of an example that might not be close enough to your real problem to solve it) about how this method is threaded and what AFunction is (or whatever it is in your code).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi!.
Yes, AFunction(AParam) is a method from a ActiveX writing in C++.
A reference to this activex is passed to the constructor of the class.
Maybe this is the problem.
Thank you very much.
|
|
|
|
|
It may be. What's the threading model for the ActiveX control?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am writing a webservice that allows a user to upload files. i had no problem handling pictures but i am having trouble handling plain text files.
How do I write out my stream to a text file that the webservice receives from the client? HOw do I take my System.IO.Stream and pass it into a FileStream so that I can write the file anywhere I want on the server?
Thanks in advance
|
|
|
|
|
Pass the Stream into the constructor of a StreamReader , then buffer the input (in blocks, for which 4096 is a good size typically) to a TextWriter derivative (perhaps a StreamWriter with a FileStream passed to its constructor that points at the right place. This will also allow you to change the encoding if you like.
You could skip the readers and writers, though, and just buffer the input directly from the Stream to a FileStream , something like:
private void Save(Stream s)
{
FileStream file = new FileStream("c:\temp\file.txt", ...);
using (file)
{
byte[] buffer = new byte[4096];
int read = 0;
read = s.Read(buffer, 0, buffer.Length);
while (read != 0)
{
file.Write(buffer, 0, read);
read = s.Read(buffer, 0, buffer.Length);
}
}
} A very simplistic example, but you should get the idea. The code would be similar using a TextReader and TextWriter derivative, but would allow you to more easily handle text as opposed to binary data (although you could still get an encoded string at any time using the Encoding class derivatives).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is there a way to access files that are currently in use by another program? I am sure that there is because backup utilities do it all the time, but I just have no idea how to do it. I would really appreciate any help. Thanks
|
|
|
|
|
It depends on the share locks. If a program locks the file for writing, then other programs can read it. If it locks it for reading, the other apps may be able to write to it. If it's locked for both (exclusive), then you'll have to wait.
See the documentation for FileStream class in the .NET Framework, which includes samples. Also see the FileShare enumeration documentation as well.
Backups are an entirely different story and this is a very low-level feature. Also, backup accounts typically (and should) have the backup security privilege that lets those accounts do much more than allowed by other accounts (including administrative accounts if they don't have those privileges.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi folks,
I'm a .net newbie and an wondering if something like this is possible in C# and .net:
I have an abstract class:
abstract public class AbstractDAO {
abstract public int Create(object obj);
...
}
And a concrete class that extends it:
public class BidDAO : AbstractDAO {
public override int Create(Bid bid) { ... };
...
}
this generates a build error because Create(Bid bid) does not effectively override Create(object obj).
The problem goes away if I change the concrete class to:
public class BidDAO : AbstractDAO {
public override int Create(object obj) { Bid bid; bid = (Bid) obj; ... };
...
}
Is there anyway around this? Or perhaps a better question is, is this the *correct* way of doing this?
Any help is much appreciated!
Ed.
|
|
|
|
|
That's one way of doing it, but don't just assume that obj is a Big . Do some type checking first, and throw an ArgumentException if the type is wrong. You could make it as simple as:
public override in Create(object obj)
{
Bid bid = obj as Big;
if (bid == null) throw new ArgumentException("Must pass a Bid object.",
"obj");
} If you want to provide typed parameters, overload Create and just have each of them call one of the Create methods that takes all parameters into account and actually contains the definition of the method.
If you don't want developers to see the overridden method, you can attribute the method with the EditorBrowsableAttribute , passing EditorBrowsableState.Never in the constructor. This doesn't mean it can't be executed, just that compliant code editors (like VS.NET) won't show it in IntelliSense.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is it possible to give the end user on the web based application the cabapility of crystal report or any other tool editor inerface, where s/he can pick the fields they want, lignment, grouping etc. and generate report dinamically?
Thanks,
|
|
|
|
|
This is not really a C#/.NET question, since you're looking for design-time support for Crystal Report definitions, which is possible but VERY costly. See the Crystal Reports[^] web site for more information.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Currently, this doesn't have all of the capabilities you are looking for, but if you have a license of SQL Server 2000 on the server you would need this capability, you can use SQL Reporting Services[^]. Supposedly, you don't have to use this against SQL Server, but I haven't seen that done. As a free tool (with a SQL Server 2000 license) that is centered around .NET, I imagine this would be a very flexible option. Not to mention that I imagine this will be extended and included in Yukon. We'll see, tho.
Michael Flanakin
Web Log
|
|
|
|
|
Hello. I got ASP.NET project and I want to create custom setup project for it. I've done following steps:
1.I created a new WebSetup project in my solution.
2.I created a new Class Project in my solution. in thid project I've add a new Installer class which inherits System.Configuration.Install.Installer.
So I overrided some functions like Install, Uninstall etc.
Also in WebSetup project in UserInterface I added a TextBoxes(A) form. My WebSetup project writes some value to the Registry "HKLM\SOFTWARE\MySoft\WebAppliction"
After all, all I need it's just to read Registry and find out if there are my application was previously installed, and if it was installed earlier I need to write Registry values into TextBoxes(A) form TextBoxes.
If I try do that in Install method it not works, because TextBoxes(A) form is shown before the Install starts and TextBoxes in TextBoxes(A) form are empty, but I want to fill them values from Registry if my key exists...
|
|
|
|
|
The installer project uses Windows Installer - there is absolutely NO need to check to see if your product exists. If the ProductCode is already registered, it will prompt to repair or remove. If you want an upgrade, keep the UpgradeCode the same, change the version number, and set RemovePrevious to true. It is recommended that .NET applications and libraries DO NOT write to the registry as this cause portability and deployment problems.
Also, when you create a custom Installer class, you have to register it as a Custom Action otherwise it won't be executed. There's no magic here. Just go to the Custom Actions tab in the setup project, right-click, and and select "Add Custom Action...". It will create custom actions for each of the catagories listed in that tab. To pass parameters from your installer package, pass command-line arguments by customizing the custom action commands that are generated to send things like /myparam1=[PARAM1] /myparam2=[PARAM2] , where PARAM1 and PARAM2 are properties defined in your installer package (which can be set using the custom dialogs). In your installer package, you can get these by querying the Context.Parameters property (a dictionary, or key/value lookup table) using the switch, like myparam1 and myparam2 like I used above.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thank you for the your information. But this is not quite that I wanted to know.
When I lunch my msi file, Wellcome scrren appears and after Next click my TextBoxes(A) form appears, and EditBoxes in that TextBoxes(A) form I want to fill by the values from the Registry if such exists.
I added Custom Action as myinstaller.dll but if I trying to read values from Registry and fill EditBoxes in TextBoxes(A) form nothing happend, because Install process starts AFTER Wellocome screen and TextBoxes(A) form appears....
|
|
|
|
|
Custom actions can be run at any time, and even in response to user interaction. The problem is that the installer project in VS.NET is EXTREMELY limited unless you know how to manually edit MSI packages - trust me, I know. I've beta tested Windows Installer since before the beginning and also helped beta-test for Wise Solutions, maker of Wise for Windows Installer (the cheaper, easier alternative to InstallShield who allows FULL access to the tables LONG before InstallShield did).
You actually don't need a custom action here, and a .NET Installer custom action can't even help you here (without interop'ing the MSI automation server, getting the current session, and do a whole lot of crap that isn't necessary).
This can be, fortunately, done through the crappy UI. In the solution explorer, select your project. At the top is several buttons. The second to the last one (before the project config button) is the Launch Conditions button. Click it to open the interface.
Right click on "Search Target Machine" and select "Add Registry Search". Give it a name (any name - for your use only) and go to the Properties window. Type in a property name, preferrably in all capital letters (this allows for a secure property which can be passed from the command line to the execution sequence, meaning you could override this value if you wanted to). Select the registry hive from the Root and type the key (exluding the value key name, so just the "directories" that you'd see in regedit.exe) in RegKey. Finally, put the name of key in Value.
One of the first things that Windows Installer does (by default, this can be changed through some order is required for other actions to work) is check launch conditions and perform searches. This will read the value of that registry key into a property with the name you provided above. In the EditProperty# type the name of this property. That's it.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanx again. But I got some new problems, if registry key does not exists, my program just could not be installed, an error notification apperas that "Setup could not continue etc. etc."
Also I want to ask you one more thing:
If I have installed my program, and than in VS.NET I rebuild my project and lunch the msi file again, then error notification appears. In this message I have been told that:
"Setup could not continue because another version of my program was previously installed. Use Add/Remove programs to remove that program"
I guess it happens because I rebuild my Setup project and my build version changed.
So, I want be able to Install, Repair or Uninstall my program just by lunching msi file once again (without removing my program(previous version) through Add/Remove Programs).
It seems to me it would be perfect if I could overrid some function that allows me to UPGRADE my programm....
Thanx again for your advises.
Excuse my English
Regards, Alex.
|
|
|
|
|
dotnetdev@univ.kiev.ua wrote:
I guess it happens because I rebuild my Setup project and my build version changed.
No, it's because your installer version did NOT change. Windows Installer has full upgrade support built in to its core, but it isn't automatic. First, in your project properties set RemovePreviousInstall (or something like that) to true. Also, between versions change the Version number appropriately (it's only 3 numbers, not 4 which really isn't supported anymore for MSIs), be it a release, minor, or major version number change appropriate for your changes to your application. The file versions are only used when Windows Installer determines if a file should be overwritten (well, it's one way). When you change the project's version number, you're asked if you want to change the product and package codes, too. Click Yes. Your UpgradeCode remains the same so your product is still associated between versions, except that only one package with the same product code can be installed at a time. That's where your error is coming from.
That registry solution I told you would not produce an error. It would leave your property undefined (so you could actually use that in a launch condition by putting just the property name in there. If it was set, the condition is true; if it wasn't set, the condition is false). Something else is causing it. A better description of the error that doesn't include "blah blah" would be far more helpful.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Unfortunatly I did not find any property like RemovePreviousInstall or something else in my project options. Could you please tell me where I can find this option more detaily.
So, when I installing my program by launching msi file product installed correctly. And when I rebuild my Setup project and try to Install it one more time by lunching new (rebuilded) msi file again message with following text appears:
"Another version of this product ia already installed. Installation cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel"
And when I remove my program through Control Panel, and then instlling again from new(rebuilded) msi file all goes well. Can you tell me if there possible to remove my program just by lunching new(rebuilded) msi file, that no message appears, and I'll not have to remove old version through Control Panel.
Thanx.
|
|
|
|
|
thanx for your advise with Registry Search it works!
But now other problem occured: In Registry I keep value as string "User=www" and if I trying to get value from Registry through Registry Search it returns me "User=www" in my TextBoxex(A) form textbox value. And I want only "www" as my TextBoxex(A) form textbox value. So could you tell me how can I parse vlues from which I recieve from registry?
|
|
|
|
|
You normally don't store registry values like that. A much more common practice would be to name the key "User" and set the corresponding value to "www". Windows Installer has its limitations. If you insist on storing your values this way, then you're responsible for having to parse them and there's not an easy way of doing it. The only way possible would be to write a custom action (in C or C++, it'd be difficult and too inefficient to do so with a .NET Installer class) that gets a handle to the current session, gets the property and splits it into new properties, all before the dialog is displayed. Then you'll need another one to put them all back before the WriteRegistryValues action.
All this would also require manual hacking of the MSI since the VS.NET installer project will be of no help and won't let you do things like this. It is not meant to be a commercial deployment replacement.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|