|
I have never experienced anything like that, nor read about it.
Are you sure your two copies are comparable, e.g. both built for release?
If the difference is there, I'm curious to see some of the relevant source.
|
|
|
|
|
The .Net 1.1 version is a class library and runs in our live system - it's a database analysis suite using an inverted index database - in the live system a query on 20 million rows returns a count of 4 million in .23 seconds - recompiling the class library and just calling it from a console app runs the same query on the same database in .38 seconds.
|
|
|
|
|
What you could try is:
- locate the/a hotspot, the/a bit of code that is dominating the execution time;
- compare the 1.1 and 3.5 versions of the IL code for that hotspot.
If the code is different, there may be ways to massage your source into better hehavior; if the IL code is basically identical, there may be nothing you can do about it. Chances are the difference is in some middleware, e.g. ADO.NET
|
|
|
|
|
There is no middleware - the database system is all mine and is hit using a BinaryReader.
I will check out the IL
|
|
|
|
|
The debug version of the .Net 1.1 assembly is as fast as the release version of the .Net 3.5 assembly. I don't have VS2003 installed anymore so I can't profile the 1.1 version. Oh well - the speed of this has been on a downward spiral for years - assembler -> C++ -> .Net 1.1 -> .Net 3.5
|
|
|
|
|
One more thought: to reduce the search area, you could slim your code down to the file I/O, i.e. skip all data processing, and see what gives. (That would require a live VS2003 of course).
|
|
|
|
|
Actually forget everything I said - I was running the test console app through Visual Studio - if I run the console app normally the 3.5 version is much faster
|
|
|
|
|
Now I'm puzzled again. Are you saying some elementary bit manipulation and file I/O is much faster in 3.5 than it is in 1.1? I'm not complaining, it just is news to me (not very relevant though, as I retired all 1.x stuff years ago, needing some of the 2.0 classes).
|
|
|
|
|
I've got char[] buffer = new char[N]; with some unicode text.
The message is less than N and all other elements are 0 in the buffer .
But when I create string from it with string str = new string(buffer); it appends all N elements including terminating zero characters that string looks like: "message\0\0\0\0\0\0\0\0\0\0\0 ... more \0 chars .
Why it does not terminate it?
Чесноков
|
|
|
|
|
This should do the job:
string str = new string(buffer).TrimEnd('\0');
Or, if you know the desired length of the string, you can try this:
string str = new string(buffer, 0, length);
|
|
|
|
|
Because C# strings are not null terminated, unlike C / C++. Because the char[] has a length, each character is transferred into a new string of the same length.
Use Trim or the buffer convert as Kubajzz suggested.
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
Hi, everyone!
Now I am developing an application using TAPI. I want to import some functions from cellcore.dll. But I don't know how to write the prototype of these functions. The functions I want to import are: lineInitializeEx, lineNegotiateAPIVersion, lineOpen, lineSetEquipmentState, lineGetEquipmentState, lineRegister, lineClose and lineShutdown. For example, I try to import lineInitializeEx with the code below:
[DllImport("cellcore.dll")]
private static extern long lineInitializeEx(ref uint phLineApp,IntPtr hInstance,IntPtr CallBackFunc,string strAppName,
ref uint dwDevNum,ref uint pdwApiVersion,ref LINEINITIALIZEEXPARAMS lineParams);
I had declare LINEINITIALIZEEXPARAMS struct previous. It can compiled. But can't be executed. The error message say it can't find the entry point for this function. I wonder the prototype is wrong. How to write it? Thx!
There is some white cloud floating on the blue sky. That's the landscape I like.
|
|
|
|
|
You may have some errors in what you've shown and what you have elsewhere.
For example, CallBackFunc generally would be a delegate on the managed side and you are returning long - LONG in C/C++ is an int/uint in C#.
I've never used the library, but from looking at MSDN, this is how I'd attempt it and tweak where needed. Always use SetLastError so you can get the last error from the system when thing go bang!
private delegate void lineCallbackFunc(
uint hDevice,
uint dwMsg,
uint dwCallbackInstance,
uint dwParam1,
uint dwParam2,
uint dwParam3);
[StructLayout(LayoutKind.Sequential)]
private struct LINEINITIALIZEEXPARAMS
{
public uint dwTotalSize;
public uint dwNeededSize;
public uint dwUsedSize;
public uint dwOptions;
public IntPtr hEvent;
public IntPtr hCompletionPort;
public uint dwCompletionKey;
}
[DllImport("cellcore.dll", SetLastError = true)]
private static extern uint lineInitializeEx(
out IntPtr lphLineApp,
IntPtr hInstance,
lineCallbackFunc lpfnCallback,
StringBuilder lpszFriendlyAppName,
out uint lpdwNumDevs,
out uint lpdwAPIVersion,
ref LINEINITIALIZEEXPARAMS lpLineInitializeExParams
);
|
|
|
|
|
I am pleasure to see your answer. Thank you!
But I have still a problem. As the code you show, the struct LINEINITIALIZEEXPARAMS has two elements: hEvent and hCompletionPort. But in C++, this struct has a union. The element in it have the same name as your code. I know the keyword "union" isn't exist in C#. But I think this struct shouldn't be declare as this.
Additional, I can't still execute this program. The error is still "No entry point found for lineInitializeEx". I hope you can help me again. Thx!
There is some white cloud floating on the blue sky. That's the landscape I like.
|
|
|
|
|
You are correct about the struct - I missed the union
[StructLayout(LayoutKind.Explict)]
private struct LINEINITIALIZEEXPARAMS
{
[FieldOffset(0)]
public uint dwTotalSize;
[FieldOffset(4)]
public uint dwNeededSize;
[FieldOffset(8)]
public uint dwUsedSize;
[FieldOffset(12)]
public IntPtr hEvent;
public IntPtr hCompletionPort;
[FieldOffset(12)]
public uint dwCompletionKey;
}
Are you sure you have the dll installed as it seems windows can't find it? If it's on your system, try using an absolute path.
|
|
|
|
|
Excellent thread, except:
DaveyM69 wrote: [FieldOffset(12)]
public uint dwCompletionKey;
IMO it is either 16 (Win32) or 20 (Win64).
|
|
|
|
|
I'm never 100% sure about unions not being a C guy. I believe that at byte 12 will be either hEvent OR dwCompletionKey .
The way I understand it is that if the handles aren't used then the size of the struct will be 16 bytes, if the handles aren't are used, then the size will be 20 bytes if Win32 or 28 if Win64. The location of dwCompletionKey /hEvent will always be 12 and only the size of the struct will be different.
Please correct me if I'm wrong!
|
|
|
|
|
Hi Dave,
This is the original definition from MSDN:
typedef struct lineinitializeexparams_tag {
DWORD dwTotalSize;
DWORD dwNeededSize;
DWORD dwUsedSize;
DWORD dwOptions;
union {
HANDLE hEvent;
HANDLE hCompletionPort;
} Handles;
DWORD dwCompletionKey;
} LINEINITIALIZEEXPARAMS, *LPLINEINITIALIZEEXPARAMS;
in C/C++ every struct member that is not inside a union block will be layed out sequentially; and everything inside a union block will share the same memory (and needs the size of the largest item), so here hEvent and hCompletionPort are overlapping, however dwCompletionKey (not being part of the union) must be at the next suitable address following the union, hence at start of union item plus 4 ot 8 depending on pointer sizes.
BTW: there seems to be a dwOptions member too, which hasn't been mentioned before!
|
|
|
|
|
Hmm... intersting. The only time I've written code requiring it was for MMTIME[^] which I have like this
[StructLayout(LayoutKind.Explicit)]
internal struct MMTIME
{
[FieldOffset(0)]
public uint wType;
[FieldOffset(4)]
public uint ms;
[FieldOffset(4)]
public uint sample;
[FieldOffset(4)]
public uint cb;
[FieldOffset(4)]
public uint ticks;
[FieldOffset(4)]
public byte hour;
[FieldOffset(5)]
public byte min;
[FieldOffset(6)]
public byte sec;
[FieldOffset(7)]
public byte frame;
[FieldOffset(8)]
public byte fps;
[FieldOffset(9)]
private byte dummy;
[FieldOffset(10)]
private ushort pad;
[FieldOffset(4)]
public uint songptrpos;
}
Luc Pattyn wrote: there seems to be a dwOptions member too, which hasn't been mentioned before!
I had that in the original reply[^] but missed it when I looked at the union
|
|
|
|
|
That looks OK; there is one union, all its members are starting at the same offset (4), and nothing is following the union (both inner structs are inside the union, the union is the last member of the outer struct).
|
|
|
|
|
|
According to P/Invoke.net, lineInitializeEx is in coredll.dll NOT cellcore.dll
|
|
|
|
|
Yes, you are right. I had success to execute it now. Thank you very much!
There is some white cloud floating on the blue sky. That's the landscape I like.
|
|
|
|
|
Following the discussion I had with Luc, I've done some investigation into the way uinions work, and he is correct, the parameters inside the union block start at the same place in memory - in otherwords, the struct will contain one of the handles but not both so the best way to declare it is:
[StructLayout(LayoutKind.Sequential)]
private struct LINEINITIALIZEEXPARAMS
{
public uint dwTotalSize;
public uint dwNeededSize;
public uint dwUsedSize;
public uint dwOptions;
public IntPtr handle;
public uint dwCompletionKey;
}
|
|
|
|
|
I'm glad to see your answer. But now I meet a new problem, that I can't get HINSTANCE. I had find some ways in MSDN. But no available way I found. Could you be kind to help me again? Thank you!
There is some white cloud floating on the blue sky. That's the landscape I like.
modified on Monday, September 13, 2010 2:03 AM
|
|
|
|
|