Changing a static variable to non-static avoids an exception
I am trying to diagnose a crash when calling a VB6 method from C# using COM interop.
The key thing is that defining a static variable referring to the VB6 object causes the crash; but making it non-static avoids the problem. I don't understand this.
This error was sporadic - sometimes occurring, other times not, without any change in inputs, etc.
I have a vague suspicion that this could be related to the VB6 DLL threading model, but very little real evidence for that other than details below. I'm not even sure this is 100% related to COM interop, it just seems likely.
VB6 code for class Calc
:
Function CalcSomething(ByVal input as Single)
CalcSomething = ... <some math using 'input'>
End Function
'other functions exist also...
A Calc
object has no internal state; it is just a collection of functions.
C# code which would crash:
static class A
{
private static Calc calc1 = new Calc();
public GetCalc() => calc1;
}
...
A.GetCalc.CalcSomething(1234); // CRASH!
C# code which does not crash:
static class A
{
public GetCalc() => new Calc();
}
...
A.GetCalc.CalcSomething(1234); // NO CRASH.
Additional details:
Error:
- Exception type:
System.AccessViolationException
- Message: "Attempted to read or write protected memory"
- Source :
Interop.CalcDLL
(which is the autogenerated COM-callable wrapper)
VB6 DLL:
Compiled with the "Apartment Threaded" setting.
Class
Calc
in that DLL is set toGlobalMultiUse
instancing.DLL is registered and referenced by the C# project
So although I have a workaround I would really like to understand what the root cause of the problem was, so it can be avoided and/or maybe fixed in a better way.
Thanks for your input!
c# vb6 com-interop
add a comment |
I am trying to diagnose a crash when calling a VB6 method from C# using COM interop.
The key thing is that defining a static variable referring to the VB6 object causes the crash; but making it non-static avoids the problem. I don't understand this.
This error was sporadic - sometimes occurring, other times not, without any change in inputs, etc.
I have a vague suspicion that this could be related to the VB6 DLL threading model, but very little real evidence for that other than details below. I'm not even sure this is 100% related to COM interop, it just seems likely.
VB6 code for class Calc
:
Function CalcSomething(ByVal input as Single)
CalcSomething = ... <some math using 'input'>
End Function
'other functions exist also...
A Calc
object has no internal state; it is just a collection of functions.
C# code which would crash:
static class A
{
private static Calc calc1 = new Calc();
public GetCalc() => calc1;
}
...
A.GetCalc.CalcSomething(1234); // CRASH!
C# code which does not crash:
static class A
{
public GetCalc() => new Calc();
}
...
A.GetCalc.CalcSomething(1234); // NO CRASH.
Additional details:
Error:
- Exception type:
System.AccessViolationException
- Message: "Attempted to read or write protected memory"
- Source :
Interop.CalcDLL
(which is the autogenerated COM-callable wrapper)
VB6 DLL:
Compiled with the "Apartment Threaded" setting.
Class
Calc
in that DLL is set toGlobalMultiUse
instancing.DLL is registered and referenced by the C# project
So although I have a workaround I would really like to understand what the root cause of the problem was, so it can be avoided and/or maybe fixed in a better way.
Thanks for your input!
c# vb6 com-interop
Your static version creates one instance ofCalc
and hands that back to whoever asks for it viaGetCalc
. The non-static version creates a new instance ofCalc
every time it's called.
– Damien_The_Unbeliever
Nov 21 '18 at 12:44
@Damien_The_Unbeliever yes, that is correct.
– DaveInCaz
Nov 21 '18 at 12:44
I'm working on a C# component that runs on top of a C++ application and all communication is done through COM. We ran into a lot of System.AccessViolationException exceptions when the C# code was running in a background thread and making COM calls. We got around this by using App.Current.Dispatcher.Invoke to do the calls on the main thread. Not sure if this is the same as your issue but thought I would throw it out there.
– Marc
Nov 21 '18 at 13:27
@Marc thanks... we aren't creating any threads manually but I do suspect that something the default (or maybe "unintentional") threading model is causing this.
– DaveInCaz
Dec 3 '18 at 13:16
add a comment |
I am trying to diagnose a crash when calling a VB6 method from C# using COM interop.
The key thing is that defining a static variable referring to the VB6 object causes the crash; but making it non-static avoids the problem. I don't understand this.
This error was sporadic - sometimes occurring, other times not, without any change in inputs, etc.
I have a vague suspicion that this could be related to the VB6 DLL threading model, but very little real evidence for that other than details below. I'm not even sure this is 100% related to COM interop, it just seems likely.
VB6 code for class Calc
:
Function CalcSomething(ByVal input as Single)
CalcSomething = ... <some math using 'input'>
End Function
'other functions exist also...
A Calc
object has no internal state; it is just a collection of functions.
C# code which would crash:
static class A
{
private static Calc calc1 = new Calc();
public GetCalc() => calc1;
}
...
A.GetCalc.CalcSomething(1234); // CRASH!
C# code which does not crash:
static class A
{
public GetCalc() => new Calc();
}
...
A.GetCalc.CalcSomething(1234); // NO CRASH.
Additional details:
Error:
- Exception type:
System.AccessViolationException
- Message: "Attempted to read or write protected memory"
- Source :
Interop.CalcDLL
(which is the autogenerated COM-callable wrapper)
VB6 DLL:
Compiled with the "Apartment Threaded" setting.
Class
Calc
in that DLL is set toGlobalMultiUse
instancing.DLL is registered and referenced by the C# project
So although I have a workaround I would really like to understand what the root cause of the problem was, so it can be avoided and/or maybe fixed in a better way.
Thanks for your input!
c# vb6 com-interop
I am trying to diagnose a crash when calling a VB6 method from C# using COM interop.
The key thing is that defining a static variable referring to the VB6 object causes the crash; but making it non-static avoids the problem. I don't understand this.
This error was sporadic - sometimes occurring, other times not, without any change in inputs, etc.
I have a vague suspicion that this could be related to the VB6 DLL threading model, but very little real evidence for that other than details below. I'm not even sure this is 100% related to COM interop, it just seems likely.
VB6 code for class Calc
:
Function CalcSomething(ByVal input as Single)
CalcSomething = ... <some math using 'input'>
End Function
'other functions exist also...
A Calc
object has no internal state; it is just a collection of functions.
C# code which would crash:
static class A
{
private static Calc calc1 = new Calc();
public GetCalc() => calc1;
}
...
A.GetCalc.CalcSomething(1234); // CRASH!
C# code which does not crash:
static class A
{
public GetCalc() => new Calc();
}
...
A.GetCalc.CalcSomething(1234); // NO CRASH.
Additional details:
Error:
- Exception type:
System.AccessViolationException
- Message: "Attempted to read or write protected memory"
- Source :
Interop.CalcDLL
(which is the autogenerated COM-callable wrapper)
VB6 DLL:
Compiled with the "Apartment Threaded" setting.
Class
Calc
in that DLL is set toGlobalMultiUse
instancing.DLL is registered and referenced by the C# project
So although I have a workaround I would really like to understand what the root cause of the problem was, so it can be avoided and/or maybe fixed in a better way.
Thanks for your input!
c# vb6 com-interop
c# vb6 com-interop
edited Nov 21 '18 at 12:36
DaveInCaz
asked Nov 20 '18 at 18:29
DaveInCazDaveInCaz
3,17231837
3,17231837
Your static version creates one instance ofCalc
and hands that back to whoever asks for it viaGetCalc
. The non-static version creates a new instance ofCalc
every time it's called.
– Damien_The_Unbeliever
Nov 21 '18 at 12:44
@Damien_The_Unbeliever yes, that is correct.
– DaveInCaz
Nov 21 '18 at 12:44
I'm working on a C# component that runs on top of a C++ application and all communication is done through COM. We ran into a lot of System.AccessViolationException exceptions when the C# code was running in a background thread and making COM calls. We got around this by using App.Current.Dispatcher.Invoke to do the calls on the main thread. Not sure if this is the same as your issue but thought I would throw it out there.
– Marc
Nov 21 '18 at 13:27
@Marc thanks... we aren't creating any threads manually but I do suspect that something the default (or maybe "unintentional") threading model is causing this.
– DaveInCaz
Dec 3 '18 at 13:16
add a comment |
Your static version creates one instance ofCalc
and hands that back to whoever asks for it viaGetCalc
. The non-static version creates a new instance ofCalc
every time it's called.
– Damien_The_Unbeliever
Nov 21 '18 at 12:44
@Damien_The_Unbeliever yes, that is correct.
– DaveInCaz
Nov 21 '18 at 12:44
I'm working on a C# component that runs on top of a C++ application and all communication is done through COM. We ran into a lot of System.AccessViolationException exceptions when the C# code was running in a background thread and making COM calls. We got around this by using App.Current.Dispatcher.Invoke to do the calls on the main thread. Not sure if this is the same as your issue but thought I would throw it out there.
– Marc
Nov 21 '18 at 13:27
@Marc thanks... we aren't creating any threads manually but I do suspect that something the default (or maybe "unintentional") threading model is causing this.
– DaveInCaz
Dec 3 '18 at 13:16
Your static version creates one instance of
Calc
and hands that back to whoever asks for it via GetCalc
. The non-static version creates a new instance of Calc
every time it's called.– Damien_The_Unbeliever
Nov 21 '18 at 12:44
Your static version creates one instance of
Calc
and hands that back to whoever asks for it via GetCalc
. The non-static version creates a new instance of Calc
every time it's called.– Damien_The_Unbeliever
Nov 21 '18 at 12:44
@Damien_The_Unbeliever yes, that is correct.
– DaveInCaz
Nov 21 '18 at 12:44
@Damien_The_Unbeliever yes, that is correct.
– DaveInCaz
Nov 21 '18 at 12:44
I'm working on a C# component that runs on top of a C++ application and all communication is done through COM. We ran into a lot of System.AccessViolationException exceptions when the C# code was running in a background thread and making COM calls. We got around this by using App.Current.Dispatcher.Invoke to do the calls on the main thread. Not sure if this is the same as your issue but thought I would throw it out there.
– Marc
Nov 21 '18 at 13:27
I'm working on a C# component that runs on top of a C++ application and all communication is done through COM. We ran into a lot of System.AccessViolationException exceptions when the C# code was running in a background thread and making COM calls. We got around this by using App.Current.Dispatcher.Invoke to do the calls on the main thread. Not sure if this is the same as your issue but thought I would throw it out there.
– Marc
Nov 21 '18 at 13:27
@Marc thanks... we aren't creating any threads manually but I do suspect that something the default (or maybe "unintentional") threading model is causing this.
– DaveInCaz
Dec 3 '18 at 13:16
@Marc thanks... we aren't creating any threads manually but I do suspect that something the default (or maybe "unintentional") threading model is causing this.
– DaveInCaz
Dec 3 '18 at 13:16
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53399315%2fchanging-a-static-variable-to-non-static-avoids-an-exception%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53399315%2fchanging-a-static-variable-to-non-static-avoids-an-exception%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Your static version creates one instance of
Calc
and hands that back to whoever asks for it viaGetCalc
. The non-static version creates a new instance ofCalc
every time it's called.– Damien_The_Unbeliever
Nov 21 '18 at 12:44
@Damien_The_Unbeliever yes, that is correct.
– DaveInCaz
Nov 21 '18 at 12:44
I'm working on a C# component that runs on top of a C++ application and all communication is done through COM. We ran into a lot of System.AccessViolationException exceptions when the C# code was running in a background thread and making COM calls. We got around this by using App.Current.Dispatcher.Invoke to do the calls on the main thread. Not sure if this is the same as your issue but thought I would throw it out there.
– Marc
Nov 21 '18 at 13:27
@Marc thanks... we aren't creating any threads manually but I do suspect that something the default (or maybe "unintentional") threading model is causing this.
– DaveInCaz
Dec 3 '18 at 13:16