|
First, comment out your try catch block, and then look at where it does happen.
Second: Put your code into <pre></pre> blocks
|
|
|
|
|
see my sig.
and use Exception.ToString() not Exception.Message
|
|
|
|
|
hi bros,
I've a problem when call the below Lotus Notes API function
STATUS LNPUBLIC NSFItemAppend(
NOTEHANDLE note_handle,
WORD item_flags,
char far *item_name,
WORD name_len,
WORD item_type,
void far *item_value,
DWORD value_len);
In C# I use platform invoke as below:
using DWORD = UInt32;
using HANDLE = IntPtr;
using STATUS = UInt16;
using WORD = UInt16;
...
[DllImport("nnotes.dll")]
public static extern STATUS NSFItemAppend(HANDLE note_handle, WORD item_flags, String item_name, WORD name_len,WORD item_type, HANDLE item_value, DWORD value_len);
The problem is that I don't know when I call it, how can I pass a pointer (HANDLE) of types such as string, TIMEDATE.. into the function.
I've thought of item_value with System.Object type but it does not help.
Please help me with this case, I really need it.
Many thanks.
|
|
|
|
|
Hi,
is this the first P/Invoke call you are trying? or are there others that succeed/fail?
You should build it up, trying the simplest methods first.
Make sure to put all the P/Invoke stuff in a big try-catch and have the catch block show the full Exception.ToString()
If you don't need note_handle on the managed side (i.e. it gets a value returned by your first Lotus call, then needs to be passed to consecutive calls), then an IntPtr is fine.
Is item_value an input? or an output?
Passing a string as input is easy, just use string ; you may want to add CharSet=CharSet.Ansi or CharSet=CharSet.Unicode to the DllImport attribute.
Passing a pointer to a number, an array, a struct takes some effort, as you must make sure the object can't get moved by the GC while native code is using it. I tend to use the GCHandle class for that, although simple cases can be solved using the fixed keyword.
BTW: I am preparing a couple of articles on P/Invoke; here[^] is a preliminary version for part 1, that might be useful.
|
|
|
|
|
Hello Everybody,
I want to create multicast delegates automatically. I am working on a solution with Attributes on methods. The plan is to have a method, that takes a few objects and creates a multicast delegate from all methods that have a certain Attribute.
In the following example I want the method ConformsToMyMulticast to be added to the multicast (because it is marked with MyAttribute).
class Program {
public delegate void MyMulticast();
static void Main(string[] args)
{
MyMulticast multi;
Test t1 = new Test();
MethodInfo[] methodList = t1.GetType().GetMethods();
foreach (MethodInfo info in methodList)
{
foreach (object o in info.GetCustomAttributes(true))
{
if (o is MyAttribute)
{
multi += info ???
}
} } }
}
class Test
{
public Test() {}
[MyAttribute()]
public void ConformsToMyMulticast() {}
}
I've been working on that for the last few hours and I really hope one of you can help me.
Thanks in advance!
|
|
|
|
|
Work with Delegate.CreateDelegate() and Delegate.Combine methods.
MyMulticast multi = delegate { };
Test t1 = new Test();
MethodInfo[] methodList = t1.GetType().GetMethods();
foreach (MethodInfo info in methodList)
{
foreach (object o in info.GetCustomAttributes(true))
{
if (o is MyAttributeAttribute)
{
Delegate d = Delegate.CreateDelegate(typeof (MyMulticast), t1, info);
multi = (MyMulticast) Delegate.Combine(multi, d);
}
}
}
multi();
Best wishes,
Navaneeth
|
|
|
|
|
It works \(^_^)/
Thank you very much.
I had experimented with Delegate.CreateDelegate , but I always got an ArgumentException .
|
|
|
|
|
Hey I am a college student and recently figured out how to down/up cast types and get derived values form them.
I made a simply (certainly not elegant) experimental program for it but I dont want to use Try/Catch in the "ShowDetails" method. There must be a better way than this !
class Program
{
static List<IProduct> productList = new List<IProduct>();
static void Main(string[] args)
{
Console.WriteLine("What product would you like to purchase");
Console.WriteLine("1 Xbox");
Console.WriteLine("2 Ps3");
Console.Write("Number: ");
char choice = Console.ReadLine()[0];
Choice ch = Makedescision(choice);
EvaluateDescision(ch);
Console.ReadKey();
}
enum Choice { xbox = 1, ps3 = 2, nothing };
static Choice Makedescision(char input)
{
if (input.Equals('1'))
{
return Choice.xbox;
}
else if (input.Equals('2'))
{
return Choice.ps3;
}
return Choice.nothing;
}
static void EvaluateDescision(Choice ch)
{
if (ch == Choice.xbox)
{
MakeNewXbox();
}
else if (ch == Choice.ps3)
{
MakeNewPs3();
}
}
static void MakeNewXbox()
{
Xbox product = new Xbox();
Console.WriteLine("Name your xbox");
product.Name = Console.ReadLine();
product.quantity = 2;
product.Cost = 129.99m;
productList.Add(product);
ShowDetail(0);
}
static void MakeNewPs3()
{
Ps3 product = new Ps3();
Console.WriteLine("Is new?");
bool isNew = bool.Parse(Console.ReadLine());
product.IsNew = isNew;
product.Cost = 129.99m;
productList.Add(product);
ShowDetail(0);
}
static void ShowDetail(int i)
{
int quantity;
bool detail;
IProduct prod = (IProduct)productList[i];
try
{
quantity = ((Xbox)(prod)).quantity;
Console.WriteLine("quantity is " + quantity);
}catch(Exception e)
{
}
try
{
detail = ((Ps3)(prod)).IsNew;
Console.WriteLine("is new? " + detail);
}
catch (Exception e)
{
}
}
}
|
|
|
|
|
Try doing a safe cast:
Xbox xb = prod as Xbox;
if (xb != null)
{
...
}
You could also use
if (prod is Xbox)
{
...
}
but the "as" cast will cope with nulls better.
[edit]Oops! put the <pre> tag in teh wrong place - fixed[/edit]
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced.
This message is made of fully recyclable Zeros and Ones
"Rumour has it that if you play Microsoft CDs backwards you will hear Satanic messages.Worse still, is that if you play them forwards they will install Windows"
|
|
|
|
|
Awesome works very well, surprisingly i have came across this "as" syntax before and surprised i didnt think about it xD
Thanks
|
|
|
|
|
You're welcome.
No trees were harmed in the sending of this message; however, a significant number of electrons were slightly inconvenienced.
This message is made of fully recyclable Zeros and Ones
"Rumour has it that if you play Microsoft CDs backwards you will hear Satanic messages.Worse still, is that if you play them forwards they will install Windows"
|
|
|
|
|
Agreed that type-safe casting is far superior to blanket try/catch in the original code.
As for "as" vs. "is"... As far as I know, "as" and "is" both cope with nulls the same way, "as", however has an advantage when you need to use the instance through the casted type, i.e. you wouldn't want to do an "is" check only to then do an "as" cast after the fact.
In any event, you should consider exposing functionality common to both product types through the IProduct interface. Inheritence is only a useful design pattern when common functionality exists at certain levels of the type heirarchy -- if you constantly have to up and down cast, you're probably forcing a flawed design.
|
|
|
|
|
vtpdawg wrote: any event, you should consider exposing functionality common to both product types through the IProduct interface. Inheritence is only a useful design pattern when common functionality exists at certain levels of the type heirarchy -- if you constantly have to up and down cast, you're probably forcing a flawed design.
I understand inheritance is only useful with common characteristics of data, this design was meant to be quick and rough test set-up so i can try and figure out my original problem. Thanks :P
|
|
|
|
|
Hello,
i want to restrict the file-access for the "IPlugin"-Object (except the same folder where the assembly is in), which i load over my AppDomain from another Assembly (which is in the same bin folder as the host-app).
But the "IPlugin"-Instance can write over "finder.PerformAction(null)" everywhere Oo what i'm doing wrong?
PermissionSet ps = new PermissionSet(PermissionState.None);
ps.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
FileIOPermission fP = new FileIOPermission(PermissionState.None);
fP.AllFiles = FileIOPermissionAccess.NoAccess;
fP.AddPathList(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, Environment.CurrentDirectory);
ps.AddPermission(fP);
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain domain = AppDomain.CreateDomain("Plugins", AppDomain.CurrentDomain.Evidence, ads, ps, CreateStrongName(System.Reflection.Assembly.GetExecutingAssembly()));
IPlugin finder = (IPlugin)domain.CreateInstanceFromAndUnwrap("MyPluginTest.dll", "MyPluginTest.IPluginTest");
finder.PerformAction(null);
|
|
|
|
|
I'm trying to read an Excel file in C# Visual Studio 2008 using oldDb. My connection gets opened successfully, but oldDb adapter doesn't fill the datatable.
Here is my code:
private void openExcel()
{
string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=""C:\MyLocation\myFile.xls"";Extended Properties=""Excel 12.0;HDR=NO;""";
OleDbConnection excelConnection = new OleDbConnection(connectionString);
excelConnection.Open();
string strSQL = "SELECT * FROM [Sheet1$]";
OleDbCommand dbCommand = new OleDbCommand(strSQL, excelConnection);
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dbCommand);
DataTable dTable = new DataTable();
dataAdapter.Fill(dTable);
aListBoxControl.DataSource = dTable;
dTable.Dispose();
dataAdapter.Dispose();
dbCommand.Dispose();
excelConnection.Close();
excelConnection.Dispose();
}
Could anyone please help me find this?
Thanks in advance.
|
|
|
|
|
It's probably because your app is being compiled for "AnyCPU" instead of x86. There are no 64-bit drivers for this, and since you cannot mix 64 adn 32 bit code in the same process, you have to force your app to compile for x86 instead of AnyCPU.
|
|
|
|
|
Thanks for the fast reply. It is x86. Moreover, dbCommand.ExecuteReader() does read the data.
|
|
|
|
|
First, you do not have to open the connection first when using a DataAdapter. The DA will open and close the connection itself.
Second, instead of filling a DataTable, change this to use a DataSet instead. I've never done this with an Excel sheet, so there may be something funky going on that I don't know about.
|
|
|
|
|
I have an unusual situation.
A call from C# to C++ using static extern references to an un-mananged dll works perfectly during execution of TestClass/TestMethod unit testing within Visual Studio 2008. However, during debug (not during Testing) and normal execution, we receive an exception from the underlying COM object for which the C++ dll is a wrapper. And, right on queue, the third party COM object gives no detail why it failed.
I cannot much paste code because of proprietary reasons, however, here is the extern from C# which works fine under the context of unit testing (TestClass/TestMethod) in VS 2008.
[DllImport("BTDataAccess.dll")]
static extern uint BTReadBu( [In, MarshalAs(UnmanagedType.BStr)] string filePath);
Few notes, we do have the c++/unmanaged copied to both the C# test project and console app. Additionally, the list of c# project refernces between test and console projects have been reviewed.
Any ideas regardless of how far out they are would be appreciated.
|
|
|
|
|
Have you tried changing calling convention:
[DllImport("BTDataAccess.dll", CallingConvention=CallingConvention.SomeCallingConvention)]
I already had problems when debugging/running by different calling conventions, as some exceptions are not thrown immediatelly on release code (but are still wrong). Maybe that's the case... maybe.
Try the charset also. I am only guessing, as I really don't know what is causing the problem.
|
|
|
|
|
Thanks for the suggestion, however, none of the five CallingConvention enum values fixed the problem.
What do you mean by charset?
On another note, we are running this as a single-threaded operation. There is a call to the c++ unmanaged dll made prior to the one in question. However, it is tasks with simply instantiating a COM object. This first call and the second one which fails is performed on the same thread. Multi-threaded operations on COM brings a lot of issues, but this isn't the case here. I realize each unit test in VS is on its own thread, however, we rigged it that calls to the same COM object are not performed from different threads.
|
|
|
|
|
You use string. There is the CallingConvention and the CharSet properties.
Also, the calling convention can be wrong in the method that was called just before. So, if you instantiate a COM object and after call a method, is possible that the instantiation is using an invalid calling convention.
But, I am unsure... why you can't simple import your Com object by Visual Studio Add Referece? It creates the the available components with the right calling convention.
|
|
|
|
|
Ok, the plot thickens.
A fellow developer wrote a bare-bones c# app that calls the c++ wrapper dll and it works from his computer. However, it fails from mine.
I tried each type of CharSet without success. Also, I tried it with callingconvention = CallingConvention.StdCall.
Btw, we used to use the automatically interop dll for calling the COM directly, however, it was very unstable. The funny thing is that stability is perfect with the approach using a hand-written c++ wrapper if called from c# under the context of visual studio unit testing.
|
|
|
|
|
Hi friends, my problem is to calculate the CRC value in the comunication between two terminal.
the string so composed:
10 02 (Start)
36 01 03 0e 57 00 00 00 29 00 00 (Data)
10 03 (End)
01 65 (CRC)
I already tried some CRC calculator but I have not found a correct calculation.
Can anyone give me some suggestions?
Thank you
Bye
|
|
|
|
|
http://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net
http://www.codeproject.com/KB/recipes/crc32_dotnet.aspx
|
|
|
|