System.Runtime.InteropServices.MarshalDirectiveException occured - vb.net

I wrote a very simple code that reads and writes from a card. I got an error:
An unhandled exception of type
'System.Runtime.InteropServices.MarshalDirectiveException' occured in
ReadandWrite.exe
Additional information: PInvoke restriction: can not return variants.
Code Snippet:
Console.WriteLine("Address = 0x3c3, Value = 0x", MX4.r_1byte(963).ToString)
I am trying to understand the error and how to fix it.

Sounds like you're forgetting to declare an Interop Type for one or more of your Public methods/properties. See this MSDN thread.

Related

SAPGUI not displaying long_text or text for unhandled custom exceptions

In SAP NetWeaver 7.52 I created an ABAP classed based exception that works fine while executing within a try catch clause in the report/program. But the custom message is not displayed in SAPGUI when the exception is not handled by a try catch clause.
What I'm looking for is that when no try catch is defined the exporting message used at the moment of the raise statements is shown in the "UNCAUGHT_EXCEPTION". I have tried redefining the get_text( ) and get_longtext( ) methods. But the ABAP Run time error does not give any useful information to the developer about the cause (which is stored in the "attr_message" attribute of the exception).
When using the "try catch" the message can be retrieved without problems, but the idea is that SAPGUI presents the developer the right message in the "ABAP Runtime Error" report.
zcx_adk_exception.abap
"! Base exception for all ABAP Development Kit (ADK) exceptions
class zcx_adk_exception definition public create public inheriting from cx_dynamic_check.
public section.
"! Initializes the exception message
"! #parameter message | Message related to the reason of the exception
methods constructor
importing value(message) type zadk_str optional.
"! Returns the message associated to the exception
methods get_message
returning value(result) type zadk_str.
methods if_message~get_text redefinition.
methods if_message~get_longtext redefinition.
private section.
data attr_message type zadk_str value ''.
endclass.
class zcx_adk_exception implementation.
method constructor ##ADT_SUPPRESS_GENERATION.
super->constructor( ).
if message is not initial.
me->attr_message = message.
endif.
endmethod.
method get_message.
result = me->attr_message.
endmethod.
method if_message~get_text.
result = me->get_message( ).
endmethod.
method if_message~get_longtext.
result = me->get_message( ).
endmethod.
endclass.
What works fine:
try.
raise exception type zcx_adk_exception exporting message = 'Base_Exception_Error'.
catch zcx_adk_exception into data(ex).
write: / 'Example 1:', ex->get_message( ).
write: / 'Example 2:', ex->get_text( ).
write: / 'Example 2:', ex->get_longtext( ).
endtry.
And the output is this:
What does not work:
" Not Catching the exception
raise exception type zcx_adk_exception exporting message = 'Base_Exception_Error'.
This results in the following message being displayed instead
Following the previously proposed idea of using a message I came up with the following code that allows the exception to be raised with a message. This allows the exception to show the right message when called within a "try catch" block and display a useful message in the "Error analysis" section of the dump generated by SAPGUI.
Solution:
"! Program to test functionalities and utilities
REPORT zsandbox_tests.
" Exception Class
CLASS lcl_exception DEFINITION INHERITING FROM cx_dynamic_check.
PUBLIC SECTION.
INTERFACES if_t100_dyn_msg.
METHODS if_message~get_text REDEFINITION.
METHODS constructor
IMPORTING VALUE(message) TYPE string.
PRIVATE SECTION.
DATA attr_message TYPE string VALUE ''.
ENDCLASS.
CLASS lcl_exception IMPLEMENTATION.
METHOD if_message~get_text.
result = attr_message.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
me->attr_message = message.
ENDMETHOD.
ENDCLASS.
" Class that raises the exception
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS main RAISING lcl_exception.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
METHOD main.
DATA raise_message TYPE string VALUE 'Custom Message for the Exception'.
RAISE EXCEPTION TYPE lcl_exception
MESSAGE e000(lcl_exception) WITH raise_message '' '' '' " The if_t100_dyn_msg supports 4 attributes: V1, V2, V3 and V4 but I only use the first one
EXPORTING message = raise_message.
ENDMETHOD.
ENDCLASS.
" Call to Main Method
START-OF-SELECTION.
TRY.
lcl_main=>main( ).
CATCH lcl_exception INTO DATA(ex).
WRITE ex->get_text( ).
ENDTRY.
This generates the following output:
When no try catch is used:
" Call to Main Method
start-of-selection.
lcl_main=>main( ).
This is the output:
TL;DR : SAP did not plan to permit the customization of a short dump by the developer.
A "short dump" is a report which is generated by the ABAP kernel when an unexpected error occurs in an ABAP program, i.e. an error due to a bug in the program (usually an uncaught exception, or non-catchable errors) or to a system failure (input/output resources, memory resources, etc.)
It's intended to help the developer analyze the cause of the error and correct it.
It's not intended to be generated on purpose, except in a situation that the developer has made theoretically impossible, but actually happens, and which is thought to require many information to analyze if it happens, hence a short dump.
If it's really your intention to generate a short dump with a message, for some purpose, there are two ways:
MESSAGE 'message text' TYPE 'X'. (often used in standard SAP programs, especially in update function modules)
RAISE SHORTDUMP ... or ... THEN THROW SHORTDUMP ... in conditional expression. Both exist since ABAP 7.53. For instance RAISE SHORTDUMP TYPE zcx_adk_exception EXPORTING message = 'Base_Exception_Error'.
The short dump will contain the message text in the Analysis section.

GetFileInfo() and LastWriteTime() is giving an error : Index was outside the bounds of the array

I have following code spinet:
UPDATE
(code above this code is creation of pdf file)
Dim PdfFileInfo As FileInfo
Dim PdfModificationTime As Date
If (FileIO.FileSystem.FileExists(strPdfFileName)) Then
PdfFileInfo = FileIO.FileSystem.GetFileInfo(strPdfFileName)
PdfModificationTime = PdfFileInfo.LastWriteTime()
End If
File is exist, but when I use GetFileInfo() and LastWriteTime() it gives an error : "Index was outside the bounds of the array"
I tried lot of things, but no luck... :(
SOLVED
Issue has been solved, answered separately !
Two important points are Here..
possibility of error at those lines which I have mentioned in the question
error : Index was outside the bounds of the array
Lets talk about 1st:
Many told that error at those lines could not be possible, I thought that too while writing a code at first, but got an error which was showing in logs.
Then I have read documentation about system function GetFileInfo().
What they say, this function gives information about file which system has "cashed" in its memory, system does this cashing periodically.
Now just think, system just cashed the file system information in its memory, now you have created a file and written something in a file and called the function GetFileInfo().
Saw the problem? See when you called a function GetFileInfo(), system doesn't have even a file object cashed in the memory. So we get fileinfo object null here and when you try to get LastWriteTime() of null object,here system throws an exception.
Solution : I have put null check using while loop on fileInfo object that is PdfFileInfo in code (and yes this problem is been tested and solved .... :) )
Now talk about 2nd:
The code referred in a question was not in a try block so any exception thrown by this function block got received in calling function. Here calling function resolved this exception in its own way and thrown an exception "Index was outside the bounds of the array" which was relevant for calling function but not reflected actual exception thrown by GetFileInfo().
Solution : put this code block in try-catch block
Thanks for all comments and discussions... :) !

Runtime errors might occur when converting 'dao.Field' to 'String'. VB6 to VB.NET

I have converted a VB6 project to VB.NET using Visual Studio 2008. I have some code that throws an error for invalid cast type when for doa.Field to String Type.
Here is the code that I am working with:
If rstLogin.BOF = True And rstLogin.EOF = True Then
MsgBox("User name not found, please try again!", , "Login")
frmLogin.txtUserName.Focus()
System.Windows.Forms.SendKeys.Send("{Home}+{End}")
Else
If Trim(inPassword) = Clean(rstLogin.Fields.Item("PassWord")) Then
Call MoveUserRecord(rstLogin)
LogUserIn = True
Else
MsgBox("Invalid Password, please try again!", , "Login")
frmLogin.txtPassword.Focus()
System.Windows.Forms.SendKeys.Send("{Home}+{End}")
End If
End If
The error is:
Unable to cast COM object of type 'dao.FieldClass' to class type 'System.String'. Instances of types that represent COM components cannot be cast to types that do not represent COM components; however they can be cast to interfaces as long as the underlying COM component supports QueryInterface calls for the IID of the interface.
The error is thrown on the part of the code for the password.
If Trim(inPassword) = Clean(rstLogin.Fields.Item("PassWord")) Then
I have tried to add .ToString() to everything that I could add it to, and I still get the same error. Can someone please tell me what I am doing wrong, and how I can fix this?
Hans Passant was really close with is answer. In order for you to fix the error, and for your code to compile correctly. You will need to use:
rstLogin.Fields("PassWord").Value.ToString()
I have tested this, and I am sure that it will work.

Serializing Exceptions WCF + Silverlight

I have a WCF service I use to submit bugs for my project. Snippet of the data class:
Private _exception As Exception
<DataMember()> _
Public Property Exception As Exception
Get
Return _exception
End Get
Set(ByVal value As Exception)
_exception = value
End Set
End Property
I have a Silverlight app that uses the WCF service to send any bugs home if and when they occur. This is the error I'm testing with:
Dim i As Integer = 5
i = i / 0
The problem is SL is banging on with this message:
System.ServiceModel.CommunicationException was unhandled by user code
Message=There was an error while trying to serialize parameter :bug. The InnerException message was 'Type 'System.OverflowException' with data contract name 'OverflowException:http://schemas.datacontract.org/2004/07/System' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
Is there some trick to get a generic .NET Exception (any InnerException) to serialize properly? I'm not doing anything funky with the exception - it's just a plain 'ol exception
Thanks for any help.
I doubt very much that you can serialize a .NET-specific type like an Exception. I recommend you create your own class to hold the parts of the exception you want serialized.
This may be a problem with implicitly casting the OverflowException into a System.Exception.
The data contract serializer is very specific. This can be good and bad.
I would try just throwing a new System.Exception to see if this works OK.
If this is the case, you may need to dumb down the exception, creating a new System.Exception with the original exception message in it.
Or, like John said, you might have a better go of it if you create a custom error class that holds the exception info.

COM: How to handle a specific exception?

i'm talking to a COM object (Microsoft ADO Recordset object). In a certain case the recordset will return a failed (i.e. negative) HRESULT, with the message:
Item cannot be found in the collection
corresponding to the requested name or
ordinal
i know what this error message means, know why it happened, and i how to fix it. But i know these things because i read the message, which fortunately was in a language i understand.
Now i would like to handle this exception specially. The COM object threw an HRESULT of
0x800A0CC1
In an ideal world Microsoft would have documented what errors can be returned when i try to access:
records.Fields.Items( index )
with an invalid index. But they do not; they most they say is that an error can occur, i.e.:
If Item cannot find an object in the
collection corresponding to the Index
argument, an error occurs.
Given that the returned error code is not documented, is it correct to handle a specific return code of `0x800A0CC1' when i'm trying to trap the exception:
Item cannot be found in the collection
corresponding to the requested name or
ordinal
?
Since Microsoft didn't document the error code, they technically change it in the future.
They did document this error code, but it's hard to find:
ErrorValueEnum:
adErrItemNotFound 3265 -2146825023 0x800A0CC1 Item cannot be found in the collection that corresponds to the requested name or ordinal.
..so, as its' a documented error code, it is safe to test for it explicitly.
You'll have to decide whether or not it is worth the risk, but I believe that it is unlikely that Microsoft will change this error code. Checking for this particular error code is a pretty robust way to go.
Yes, it is fine. It is in fact a documented error code, although finding them is never easy. It is defined in the msdao15.idl Windows SDK file, adErrItemNotFound (error 3265)